I added a new CLOB Column in a table and modified my hbm.xml - file to use this new column (the old column was varchar2 and therefore too small):
(I used random-names for demonstration purposes)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="test.com.TestDO" table="TESTTABLE">
<id name="id" type="java.lang.Integer">
<column name="ID"/>
<generator class="sequence">
<param name="sequence">SEQ_SEQUENCENAME</param>
</generator>
</id>
</property>
<property name="columnName1" type="java.util.Date">
<column name="COLUMN_NAME1"/>
</property>
<property name="columnName2" type="java.lang.String">
<column name="COLUMN_NAME2"/>
</property>
<property name="columnName3" type="java.lang.String">
<column name="COLUMN_CLOB"/>
</property>
</class>
</hibernate-mapping>
As you can see, my clob-column (COLUMN_CLOB) is defined as last, because first I got this exception:
ORA-24816: Expanded non LONG bind data supplied after actual LONG or LOB column
I searched for this error and the solution was to place the clob binding at the last in the insert-statement, so I defined the clob-column in the hbm.xml file to be last, as you can see above.
Now I am not getting the ORA-24816 exception, but I am getting this exception:
ORA-01461: can bind a LONG value only for insert into a LONG column
The generated Insert-Statement looks like this:
insert into TESTTABLE(COLUMN_NAME1, COLUMN_NAME2, COLUMN_CLOB, ID) values (?, ?, ?, ?)];
As you may have noticed, the COLUMN_CLOB - column does not appear last in the generated Insert-Statement. I don't know if the order in the hbm-xml -file affects the order of the columns in the generated insert-statement?
But anyway, I am not getting the ORA-24816 anymore just ORA-01461. I don't know how to solve this issue.
I am using Hibernate 3 and Oracle Version: Enterprise Edition Release 11.2.0.4.0 - 64bit Production
EDIT:
I have the exact same issue as described here:
http://newtechnobuzzz.blogspot.ch/2014/07/ora-24816-expanded-non-long-bind-data.html#.Wcy-QdFpHRY
I have tried the following solutions:
Chaning the order of getter and setter methods does not work
Changing the order of the declared property in the hbm.xml -file does
not work
The problem described on the link and on other sites, state that this excpetion
occurs if you try to insert data in both the varchar2 and the clob columns (2 strings with a length of 4000). However I am only inserting data into the clob-column which is bigger then 4000. I am not using the old varchar2 - column anymore.
Now, I am trying to solve this by using this solution:
It can solved by writing two update queries. Firstly, save/update the entity by an Update query and then write another query to update LOB columns in that entity.
However, I dont quite understand, how I should modify my code. My method looks like this:
#Override
#Transactional(readOnly=false, propagation=Propagation.MANDATORY)
public TestDO saveTest(TestDO test) {
getHibernateTemplate().saveOrUpdate(test);
return test;
}
From what I can see, the property type has not been declared correctly for the CLOB column, try that:
<property name="columnName3" length="100000" type="StringClob">
<column name="COLUMN_CLOB"/>
</property>
I am using Hibernate 3.2.5. I am getting the above exception while using many-to-one mapping. The training table is having a many to one relation with Department table, i.e. One Depatement is capable of taking more than one training.
The exception is asking me to add insert="false" update="false" in my hbm file. If I add this bit in hbm file, then the code works fine.
Here is the hbm file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.infy.model.Training" table="training">
<id name="Id" type="integer" column="ID">
<generator class="assigned"></generator>
</id>
<property name="trainerName">
<column name="TRAINER_NAME"></column>
</property>
<property name="deptId">
<column name="DEPT_ID"></column>
</property>
<property name="trainingSubject">
<column name="TRAINING_SUBJECT"></column>
</property>
<many-to-one name="departmentDetails" column="DEPT_ID"></many-to-one>
</class>
</hibernate-mapping>
If I change this line to:
<many-to-one name="departmentDetails" column="DEPT_ID" insert="false" update="false"></many-to-one>
Then the code works. I want to know what is the exact reason for adding this.
Regards,
You have mapped the DEPT_ID column twice, here:
<property name="deptId">
<column name="DEPT_ID"></column>
</property>
And here:
<many-to-one name="departmentDetails" column="DEPT_ID"></many-to-one>
When executing a select statement, Hibernate will be fine populating two properties of your object from the same column, however when doing an insert or an update it cannot decide which property to persist in the database.
Why do you need two properties mapped to the same column in the first place? If you need access to the deptId, you can probably remove the deptId property and instead do
training.getDepartmentDetails().getId()
The error message for this scenario is quite clear (you haven't put it here, but I've seen it a few times). The problem is that you've mapped the column DEPT_ID to two different fields in your class.
First, you've mapped it to the property deptId and then to departmentDetails. As you found out, hibernate allows to do this only if one of the mappings is configured to be insert="false" update="false".
The reason is quite simple. If you would change deptId to another id, hibernate would need to change the class that is mapped in departmentDetails, which is quite complicated.
if you need to get the deptId, you can add a getDeptId method on Training that returns departmentDetails.getId(). And don't provide a setDeptId.
If you are using the same column name twice in your mapping file. might be you get mapping Exception
Initial SessionFactory creation failed.org.hibernate.MappingException:
Also if u mark insert=flase and update=false .
if u try to update or insert in records in table or another legacy system try to update these column value. it wouldn't update or insert that filed.
Please check the below link .it will help to find your solutions.
http://www.techienjoy.com/hibernate-insert-update-control.php
Thanks
Sandeep G.
I've got a hibernate problem that I can't fix.
The setup: Java EE, web app, Hibernate 3.2, Tomcat 6, Struts 2.
Basically, I persist an object with my server logic (a struts action), then try and pull that data out for the next page and display it.
I check the database after I save the object, and sure enough, I can see the row there with all the data.
But when I try and retrieve it I get this:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [msc.model.Picture#73]
To make things even muddier, when I restart Tomcat and try and access the same object, I don't get the error - Hibernate finds the row just fine.
Hibernate will also be able to see the row if I do some other operations - maybe add a row here and there to the database, not even on the same table.
From all this I suspect a Hibernate bug, but I'm a Hibernate newbie so I am probably wrong. Please help! I've googled and googled to no avail.
Here is my Hibernate config:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/msc</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">-------</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">80</property>
<property name="current_session_context_class">thread</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping resource="msc/model/Picture.hbm.xml"/>
<mapping resource="msc/model/Comment.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Here are my two mapping files:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="msc.model.Picture" table="PICTURE">
<id column="PICTURE_ID" name="id">
<generator class="native"/>
</id>
<property name="story"/>
<property name="email"/>
<property name="category"/>
<property name="state"/>
<property name="ratings"/>
<property name="views"/>
<property name="timestamp"/>
<property name="title"/>
<property lazy="true" name="image" type="blob">
<column name="IMAGE"/>
</property>
<property lazy="true" name="refinedImage" type="blob">
<column name="REFINEDIMAGE"/>
</property>
<property lazy="true" name="thumbnail" type="blob">
<column name="THUMBNAIL"/>
</property>
<bag cascade="save-update" lazy="true" name="comments" table="COMMENT">
<key column="PICTURE"/>
<one-to-many class="msc.model.Comment"/>
</bag>
</class>
</hibernate-mapping>
and
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="msc.model.User" table="USER">
<id column="USER_ID" name="id">
<generator class="native"/>
</id>
<property name="username"/>
<property name="email"/>
<bag cascade="save-update" lazy="true" name="pictures" table="PICTURE">
<key column="USER"/>
<one-to-many class="msc.model.Picture"/>
</bag>
<bag cascade="save-update" lazy="true" name="comments" table="COMMENT">
<key column="USER"/>
<one-to-many class="msc.model.Comment"/>
</bag>
</class>
</hibernate-mapping>
Please let me know if you need more info, I'm happy to oblige.
(note: this is not a duplicate of this question, the scenario is not the same "No row with the given identifier exists" although it DOES exist)
EDIT: as requested, posting Java code:
Code to save object
Session hib_ses = HibernateUtil.getSessionFactory().getCurrentSession();
hib_ses.beginTransaction();
hib_ses.save(user);
hib_ses.getTransaction().commit();
Code to display data (an image in this case)
public class ImageAction extends ActionSupport implements ServletResponseAware, SessionAware {
private HttpServletResponse response;
Map session;
private Long id;
private int thumbnail;
private InputStream inputStream;
#Override
public String execute() throws Exception {
response.setContentType("image/jpeg");
Session hib_session = HibernateUtil.getSessionFactory().getCurrentSession();
hib_session.beginTransaction();
//what is the ID now?
Picture pic = (Picture) hib_session.load(Picture.class, getId());
if (thumbnail == 1) {
inputStream = (ByteArrayInputStream) pic.getThumbnail().getBinaryStream();
} else {
inputStream = (ByteArrayInputStream) pic.getRefinedImage().getBinaryStream();
}
hib_session.close();
return SUCCESS;
}
This happens because you have inserted something which is meant to be a foreign key but do not reference anything.
Check out you database whether that key exist or not(even though it is in database in other tables).
Check all your mappings and database settings. It may be possible you are setting some not-null="true" in foreign key relations when your database says nullable="true". The first causes an INNER JOIN and the second causes LEFT JOIN.
Set log level to TRACE to see all steps and look for generated SQL when retrieving the objects.
In many to one relationship you need to tell Hibernate what needs to be done if the mapped row is not found. You can configure it in the following ways:
Annotation:
#NotFound(action = NotFoundAction.IGNORE)
Mapping XML:
<many-to-one name="user" column="user_id" class="com.xyz.User" cascade="save-update, evict" not-found="ignore"/>
Just check your database whether id 73 is available or not in your particular table
Okay, I am going to throw out a theory here. Could it be that you are trying to load the picture the first time before the transaction has been committed?
Since the transaction is not yet committed, the row is not visible to the transaction you are using for reading the picture (depends on what transaction isolation level you have).
Then, since hib_session.close() is not inside a finally block, it will not be executed, and the thread-bound session will still have an open transaction. The subsequent request gets the same Hibernate session, with the same open transaction, and you get the same result from the select it issues (again, dependent on transaction isolation level - see documentation here, in particular for REPEATABLE_READ).
This could also explain why flush() makes it slightly better, because if the flush() occurs earlier than the commit(), there's a smaller chance for the race condition to occur.
I suggest you try closing the session in a finally block and see if the behavior changes for subsequent requests.
I Faced this issue and here is What happened and How i resolved it. You most probably have the same thing going on too.
I had POST and USER objects. They are in a OneToMany relationship(A user can have many posts). Making it bidirectional they are in a ManyToOne relationship too (one post belongs to only one user).
Post class looks
#Entity
#Table(name="Post")
public class Post {
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
private long postId;
private String title;
private String body;
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "postUserId")
private AutoUser autoUser;
// getter and setters
User class is
#Entity
#Table(name = "AUTO_USER")
public class AutoUser implements UserDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long autoUserId;
#Column(name = "USERNAME")
private String username;
#OneToMany
private List<Post> postList = new ArrayList<>();
// getter and setters
The first table names were Post and AUTO_USER I had 3 users persisted to a AUTO_USER table(with id 1, 2, 3).. And 3 entry to the Post table 1 for each user.
(the join columns or foreign key were 1, 2, 3)
Then I changed only the table name for the user object only and named it #Table(name = "AUTO_USER2").
and I had only one user in this table with id 1.
In my code I iterate over each post and identify which post belongs to which user and display them those belonging to the current logged in user.
After changing the post table name I got this exception
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.tadtab.core.authentication.AutoUser#2
Which is telling me that the user object with id 2 is not available in the new user Table.
then I registered one more user with id 2 and later I got this
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.tadtab.core.authentication.AutoUser#3
This time it could not find user with id 3
Finally registered a third user and had not exception.
As you can see, the foreign key exists in the post table but since I changed the user table, there could not be a match for them and that is the reason I was facing this issue.
To avoid that situation I created new table names for both objects and started fresh
Hope this will help
I don't see any real problems pertaining to the exception in the code, you might wanna try:
Checking that the transaction is flushed or calling flush() manually after committing;
Checking whether the ID is passed to load() and whether the right ID is passed to it via debugger
Enabling Hibernate to print the generated SQL and/or enabling logging
I have a similar problem with hibernate 3.6.10, while I'm just searching and selecting (if exist).
Annotation:
#Entity
public class Familiares {
#OneToMany(mappedBy = "familiares")
private List<FamiliaresBaja> bajas;
#Entity
#Table(name = "familiares_baja")
public class FamiliaresBaja implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#JoinColumn(name = "familiares_id")
#ManyToOne(optional = false)
private Familiares familiares;
then i retrieve a List and with these looking in FamiliaresBaja if there is at least one.
createQuery("from FamiliaresBaja where familiares.id="+ id).uniqueResult() // should return a single result or null not throw a Exception
This must be a Hibernate bug
Please check the value of lower_case_table_names of your mysql server. If its value is 0, check the SQL generated by hibernate, make sure the table name's case is consistent with the actual table name in mysql.
Check triggers, if you have a before insert trigger, and having NEXTVAL in the sequence, cause that error.
You may have a one-to-one relationship in the entity you are looking for with a different ID, try to load the entity with the ID in the mapped table rather then the identity column.
The correct way to solve this problem is to use session.get() method. Get method will return null if entity is not found.
Caused by: org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.emmanuel.Entity.Classe#17]
at org.hibernate.boot.internal.StandardEntityNotFoundDelegate.handleEntityNotFound(StandardEntityNotFoundDelegate.java:28)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:216)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:327)
at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:108)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:74)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
at org.hibernate.internal.SessionImpl.fireLoadNoChecks(SessionImpl.java:1215)
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1080)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:697)
at org.hibernate.type.EntityType.resolve(EntityType.java:464)
at org.hibernate.type.ManyToOneType.resolve(ManyToOneType.java:240)
at org.hibernate.engine.internal.TwoPhaseLoad$EntityResolver.lambda$static$0(TwoPhaseLoad.java:576)
at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntityEntryLoadedState(TwoPhaseLoad.java:221)
at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:155)
at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:126)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1201)
at org.hibernate.loader.Loader.processResultSet(Loader.java:1009)
at org.hibernate.loader.Loader.doQuery(Loader.java:967)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357)
at org.hibernate.loader.Loader.doList(Loader.java:2868)
at org.hibernate.loader.Loader.doList(Loader.java:2850)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2682)
at org.hibernate.loader.Loader.list(Loader.java:2677)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:109)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1906)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:370)
I had this same problem, I had previously deleted an object which was referenced in another table and when I loaded the objects I had a foreign key in the table which did not refer to anything hence this exception.
[com.emmanuel.Entity.Classe#17] specifies that the object which is referenced with id 17 in the table whose objects I want to load does not exist.
My issue was that the child in the relation had a FK which didn't map to the PK of the parent so I had to change the JoinColumn to include referencedColumnName
#Entity
#Table(name = "child")
class Child {
#ManyToOne
#JoinColumn(name = "child_id", referencedColumnName = "non_pk_parent_id")
var iabCategory: IabCategory
}
Note that this caused another issue because of a bug in Hibernate. Here's a stackoverflow post on it:
Jpa Repository got error cannot not serializable when get data from database
and the link to the Hibernate bug: https://hibernate.atlassian.net/browse/HHH-7668
This bug forced me to mark the parent Serializable
#Entity
#Table(name = "parent")
class Parent : Serializable {
}
The bug would cause a ClassCastException to be thrown if the parent didn't implement Serializable
i am trying to load a hibernate object ForumMessage but in it contain another object Users and the Users object is not being loaded.
My ForumMessage Mapping File:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Jan 4, 2011 10:10:29 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.Models.ForumMessage" table="FORUMMESSAGE">
<id name="ForumMessageId" type="long">
<column name="FORUMMESSAGEID" />
<generator class="native" />
</id>
<property name="ForumMessage" type="java.lang.String">
<column name="FORUMMESSAGE" />
</property>
<many-to-one name="User" class="com.BiddingSystem.Models.Users" fetch="join">
<column name="UserId" />
</many-to-one>
<property name="DatePosted" type="java.util.Date">
<column name="DATEPOSTED" />
</property>
<many-to-one name="Topic" class="com.BiddingSystem.Models.ForumTopic" fetch="join">
<column name="TopicId" />
</many-to-one>
</class>
</hibernate-mapping>
and I am using the follwing code:
Session session = gileadHibernateUtil.getSessionFactory().openSession();
SQL="from ForumMessage";
System.out.println(SQL);
Query query=session.createQuery(SQL);
System.out.println(query.list().size());
return new LinkedList <ForumMessage>(query.list());
<many-to-one name="User" class="com.BiddingSystem.Models.Users" fetch="join" lazy="false">
You need to add lazy="false" as well.
You can add lazy="false" to the many-to-one mapping which will load the users when the ForumMessage is loaded. Alternatively you could initialize the users list using Hibernate.initialize(). Just make sure you do this before you close the session.
Session session = gileadHibernateUtil.getSessionFactory().openSession();
string sql = "from ForumMessage";
Query query = session.createQuery(sql);
List results = query.list()
for(ForumMessage message : results)
{
Hibernate.initialize(message.User);
}
return new LinkedList <ForumMessage>(results);
You should only do one of these though if you have a need to. Hibernate by default lazy loads objects to avoid unnecessary calls to the database. For example:
public LinkedList getMessages()
{
//It's assumed the session is opened and closed elsewhere.
string sql = "from ForumMessage";
Query query = session.createQuery(sql);
List results = query.list();
//The overhead of extra calls to the database occur here.
//This would have a similar impact if lazy load is set to false.
for(ForumMessage message : results)
{
Hibernate.initialize(message.User);
}
return new LinkedList <ForumMessage>(results);
}
public void printMessages()
{
LinkedList messages = getMessages();
for(ForumMessage message : messages)
{
System.out.println(message.ForumMessage);
}
}
In the above code sample the overhead is incurred for loading all the Users objects but those objects are never used. If Hibernate's lazy-loading were used then this extra overhead would not be incurred. In the following example the list of users isn't loaded until the list is used. This way calls are not made to the database until the data is actually needed.
public LinkedList getMessages()
{
//It's assumed the session is opened and closed elsewhere.
string sql = "from ForumMessage";
Query query = session.createQuery(sql);
List results = query.list();
return new LinkedList <ForumMessage>(results);
}
public void printMessages()
{
LinkedList messages = getMessages();
for(ForumMessage message : messages)
{
//Hibernate will load the users objects here when they are accessed.
for(Users user : message.User)
{
System.out.println(user);
}
}
}
One point to be careful of when lazy loading is all loading must be done in an active session. If you don't have an active session and you try and access something that has not yet been loaded Hibernate will throw a LazyInitializationException.
In addition, using Hibernate's lazy load functionality complies more with the idea of persistence ignorance where as using Hibernate.initialize() does not.
I am getting the following exception while adding data into database:
org.hibernate.HibernateException: The database returned no natively generated identity value
I am using the following code:
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
session.save(user);
logger.info("Successfully data insert in database");
tx.commit();
isSaved = true;
Please let me know what is wrong. Thankx
It seems as if the database doesn't support the identity id generator. Based on your mapping you are probably using the userName as the ID column, which would mean that you probably want to set the generator class to assigned since the username (= id) will be picked manually (and not auto generated by the database):
<hibernate-mapping>
<class name="com.test.User" table="user">
<id name="userName" column="user_name">
<generator class="assigned" />
</id>
<property name="userCode">
<column name="user_code" />
</property>
</class>
</hibernate-mapping>