Found shared references to a collection org.hibernate.HibernateException

我怕爱的太早我们不能终老 提交于 2019-11-26 22:18:25
ChssPly76

Hibernate shows this error when you attempt to persist more than one entity instance sharing the same collection reference (i.e. the collection identity in contrast with collection equality).

Note that it means the same collection, not collection element - in other words relatedPersons on both person and anotherPerson must be the same. Perhaps you're resetting that collection after entities are loaded? Or you've initialized both references with the same collection instance?

dgt

I had the same problem. In my case, the issue was that someone used BeanUtils to copy the properties of one entity to another, so we ended up having two entities referencing the same collection.

Given that I spent some time investigating this issue, I would recommend the following checklist:

  • Look for scenarios like entity1.setCollection(entity2.getCollection()) and getCollection returns the internal reference to the collection (if getCollection() returns a new instance of the collection, then you don't need to worry).

  • Look if clone() has been implemented correctly.

  • Look for BeanUtils.copyProperties(entity1, entity2).

Explanation on practice. If you try to save your object, e.g.:

Set<Folder> folders = message.getFolders();
   folders.remove(inputFolder);
   folders.add(trashFolder);
   message.setFiles(folders);
MESSAGESDAO.getMessageDAO().save(message);

you don't need to set updated object to a parent object:

message.setFiles(folders);

Simple save your parent object like:

Set<Folder> folders = message.getFolders();
   folders.remove(inputFolder);
   folders.add(trashFolder);
   // Not set updated object here
MESSAGESDAO.getMessageDAO().save(message);

Reading online the cause of this error can be also an hibernate bug, as workaround that it seems to work, it is to put a:

session.clear()

You must to put the clear after getting data and before commit and close, see example:

//getting data
SrReq sr = (SrReq) crit.uniqueResult();
SrSalesDetailDTO dt=SrSalesDetailMapper.INSTANCE.map(sr);
//CLEAR            
session.clear();
//close session
session.getTransaction().commit();
session.close();
return dt;

I use this solution for select to database, for update or insert i don't know if this solution can work or can cause problems.

My problem is equal at 100% of this: http://www.progtown.com/topic128073-hibernate-many-to-many-on-two-tables.html

In my case, I was copying and pasting code from my other classes, so I did not notice that the getter code was bad written:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "credito")
public Set getConceptoses() {
    return this.letrases;
}

public void setConceptoses(Set conceptoses) {
    this.conceptoses = conceptoses;
}

All references conceptoses but if you look at the get says letrases

raji

I too got the same issue, someone used BeanUtils.copyProperties(source, target). Here both source and target, are using the same collection as attribute.

So i just used the deep copy as below..

How to Clone Collection in Java - Deep copy of ArrayList and HashSet

Dinesh Angolkar

I faced similar exception in my application. After looking into the stacktrace it was clear that exception was thrown within a FlushEntityEventListener class.

In Hibernate 4.3.7 the MSLocalSessionFactory bean no longer supports the eventListeners property. Hence, one has to explicitly fetch the service registry from individual Hibernate session beans and then set the required custom event listeners.

In the process of adding custom event listeners we need to make sure the corresponding default event listeners are removed from the respective Hibernate session.

If the default event listener is not removed then the case arises of two event listeners registered against same event. In this case while iterating over these listeners, against first listeners any collections in the session will be flagged as reached and while processing the same collection against second listener would throw this Hibernate exception.

So, make sure that when registering custom listeners corresponding default listeners are removed from registry.

Tarun

Consider an entity:

public class Foo{
private<user> user;
/* with getters and setters */
}

And consider an Business Logic class:

class Foo1{
List<User> user = new ArrayList<>();
user = foo.getUser();
}

Here the user and foo.getUser() share the same reference. But saving the two references creates a conflict.

The proper usage should be:

class Foo1 {
List<User> user = new ArrayList<>();
user.addAll(foo.getUser);
}

This avoids the conflict.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!