Hibernation error: another object with the same identifier value was already associated with the session

Essentially, I have some objects in this configuration (the real data model is a bit more complicated):

  • A has many-to-many relationship with B. (B has inverse="true" )
  • B has a multi-valued relationship with C. (My cascade set to "save-update" )
  • C is the type of type / category table.

Also, I should probably mention that primary keys are generated by the database when stored.

With my data, I sometimes encounter problems when A has many different B-objects, and these B objects belong to the same C object.

When I call session.saveOrUpdate(myAObject) , I get a sleep error: "a different object with the same identifier value was already associated with the session: C" . I know that hibernation cannot insert / update / delete the same object twice in the same session, but is there any way to do this? It does not look like this would be a rarity.

During my research on this problem, I saw people suggest using session.merge() , but when I do this, any "conflicting" objects are inserted into the database as empty objects with all values ​​equal to zero. Clearly, this is not what we want.

[Edit] Another thing that I forgot to mention is that (for reasons not dependent on architecture) each reading or writing must be done in a separate session.

+72
java hibernate
Apr 26 '13 at 23:35
source share
17 answers

Most likely, this is due to the fact that objects B do not belong to the same instance of the Java object C. They refer to the same row in the database (i.e., to the same primary key), but they are different copies.

So what happens is that the Hibernate session that manages the entities will keep track of which Java object matches the string with the same primary key.

One option is to make sure that the objects of objects B that belong to the same row actually refer to the same instance of object C. Alternatively, turn off cascading for this member variable. So when B is saved, C is not. However, you will have to save C manually separately. If C is a type / category table, then it probably makes sense to be that way.

+75
Apr 26 '13 at 23:57
source share

Just set the cascade to MERGE, this should do the trick.

+21
Aug 08 '15 at 21:21
source share

You only need to do one thing. Run session_object.clear() and then save the new object. This will clear the session (as exactly named) and remove the offensive duplicate from the session.

+10
Sep 18 '14 at 7:55
source share

I agree with @Hemant Kumar, thank you very much. By solving it, I solved my problem.

For example:

 @Test public void testSavePerson() { try (Session session = sessionFactory.openSession()) { Transaction tx = session.beginTransaction(); Person person1 = new Person(); Person person2 = new Person(); person1.setName("222"); person2.setName("111"); session.save(person1); session.save(person2); tx.commit(); } } 

Person.java

 public class Person { private int id; private String name; @Id @Column(name = "id") public int getId() { return id; } public void setId(int id) { this.id = id; } @Basic @Column(name = "name") public String getName() { return name; } public void setName(String name) { this.name = name; } } 

This code always makes a mistake in my application: A different object with the same identifier value was already associated with the session , later I found that I forgot to automatically increase my primary key!

My solution is to add this code to your primary key:

 @GeneratedValue(strategy = GenerationType.AUTO) 
+6
Jan 25 '17 at 8:13
source share

Transfer the task of assigning an object identifier from Hibernate to the database using:

 <generator class="native"/> 

This solved the problem for me.

+5
Jul 24 '14 at 17:26
source share

One way to solve the above problem is to override hashcode() .
Also clear the hibernation session before and after saving.

 getHibernateTemplate().flush(); 

Also explicit binding of the selected object to null .

+3
Oct 07 '14 at 5:40
source share

Add the @GeneratedValue annotation to the bean you are inserting.

+3
Mar 26 '15 at 12:01
source share

This means that you are trying to save multiple rows in your table with a reference to the same object.

check the id property of your Entity Class.

 @Id private Integer id; 

at

 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(unique = true, nullable = false) private Integer id; 
+3
Mar 23 '18 at 7:19
source share

Just stumbled upon this post, but in C # code. Not sure if this is relevant (exact same error message).

I debugged code with breakpoints and expanded some collections through private members, while the debugger was at the breakpoint. After restarting the code without digging into the structures, the error message will disappear. It seems that searching for private collections with lazy loading made NHibernate load things that were not loaded at that time (because they were in private members).

The code itself is enclosed in a rather complex transaction, which can update a large number of records and many dependencies as part of this transaction (import process).

Hopefully the key is to someone else who is facing the problem.

+2
Jun 18 '14 at 9:54 on
source share

Find the Cascade attribute in sleep mode and delete it. When you install an accessible Cascade, it will invoke other operations (save, update, and delete) on other objects that are related to related classes. The same meaning of identity will occur. He worked with me.

+2
Apr 13 '17 at 13:51 on
source share

I had this error for several days in a row, and I spent too much time fixing this error.

  public boolean save(OrderHeader header) { Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); try { session.save(header); for (OrderDetail detail : header.getDetails()) { session.save(detail); } transaction.commit(); session.close(); return true; } catch (HibernateException exception) { exception.printStackTrace(); transaction.rollback(); return false; } } 

Before I get this error, I did not have the mentioned type of generating the OrderDetil object identifier. when without generating an Orderdetails identifier, it stores the Id as 0 for each OrderDetail object. this is what #jbx explained. Yes, this is the best answer. this example is how this happens.

+1
Jun 27 '15 at 18:45
source share

Try putting your request code earlier. This fix my problem. for example change this:

 query1 query2 - get the error update 

:

 query2 query1 update 
+1
Feb 10 '17 at 7:40
source share

You cannot set the object identifier before invoking the update request.

0
Nov 11 '13 at 9:59
source share

I met a problem due to the fact that primary key generation is erroneous when I insert a line like this:

 public void addTerminal(String typeOfDevice,Map<Byte,Integer> map) { // TODO Auto-generated method stub try { Set<Byte> keySet = map.keySet(); for (Byte byte1 : keySet) { Device device=new Device(); device.setNumDevice(DeviceCount.map.get(byte1)); device.setTimestamp(System.currentTimeMillis()); device.setTypeDevice(byte1); this.getHibernateTemplate().save(device); } System.out.println("hah"); }catch (Exception e) { // TODO: handle exception logger.warn("wrong"); logger.warn(e.getStackTrace()+e.getMessage()); } } 

I change id generator class to identity

 <id name="id" type="int"> <column name="id" /> <generator class="identity" /> </id> 
0
Dec 14 '17 at 6:28
source share

In my case, only flush () did not work. I should have used clear () after flush ().

 public Object merge(final Object detachedInstance) { this.getHibernateTemplate().flush(); this.getHibernateTemplate().clear(); try { this.getHibernateTemplate().evict(detachedInstance); } } 
0
Mar 19 '18 at 13:00
source share

if you use EntityRepository then use saveAndFlush instead of save

0
Nov 20 '18 at 14:14
source share

If you leave the expression tab open in my IDE, which made a call to get Hibernate for the object that throws this exception. I tried to delete the same object. I also had a breakpoint on the delete call, which seems to be necessary for this error to occur. Simply creating another expression tab as the front tab, or changing the settings so that ide doesn't stop at breakpoints, solved this problem.

0
Apr 29 '19 at 20:12
source share



All Articles