find对集合org.hibernate.HibernateException的共享引用

我得到这个错误信息:

错误:find对集合的共享引用:Person.relatedPersons

当我试图执行addToRelatedPersons(anotherPerson)

 person.addToRelatedPersons(anotherPerson); anotherPerson.addToRelatedPersons(person); anotherPerson.save(); person.save(); 

我的域名:

 Person { static hasMany = [relatedPersons:Person]; } 

任何想法为什么发生这种情况

当你试图持久化多个共享同一个集合引用的实体实例(比如集合相等的集合标识)时,Hibernate会显示这个错误。

请注意,这意味着相同的集合 ,而不是集合元素 – 换言之,相关person和其他person必须是相同的。 也许你正在加载实体后重置该集合? 或者你已经使用同一个集合实例初始化了两个引用?

我有同样的问题。 在我的情况下,问题是有人用BeanUtils将一个实体的属性复制到另一个实体,所以我们结束了两个实体引用相同的集合。

鉴于我花了一些时间来研究这个问题,我会推荐以下清单:

  • 查找诸如entity1.setCollection(entity2.getCollection())类的场景,并且getCollection返回集合的内部引用(如果getCollection()返回集合的新实例,则不需要担心)。

  • 看看clone()是否已经正确实现。

  • 寻找BeanUtils.copyProperties(entity1, entity2)

对实践的解释。 如果您尝试保存您的对象,例如:

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

您不需要将更新的对象设置为父对象:

 message.setFiles(folders); 

简单的保存你的父对象,如:

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

在我的情况下,我是从其他类复制粘贴代码,所以我没有注意到getter代码写得不好:

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

所有参考文献的概念,但如果你看看get说letrases

在线阅读这个错误的原因也可能是一个hibernate错误 ,作为解决方法 ,它似乎工作,它是把一个:

 session.clear() 

获取数据之后,提交并closures之前,您必须先清除数据,请参阅示例:

 //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; 

我使用这个解决scheme来select数据库,更新或插入我不知道这个解决scheme是否可以工作或可以导致问题。

我的问题是相同的100%: http : //www.progtown.com/topic128073-hibernate-many-to-many-on-two-tables.html

我也得到了同样的问题,有人用BeanUtils.copyProperties(源,目标)。 这里源和目标都使用与属性相同的集合。

所以我只用了下面的深层副本

http://javarevisited.blogspot.com/2014/03/how-to-clone-collection-in-java-deep-copy-vs-shallow.html

让我解释清楚这个错误是什么,

让我从一个例子开始,

考虑一个实体

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

并考虑一个业务逻辑类

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

这里用户和foo.getUser共享相同的参考。 同时保存两个引用会产生冲突。

正确的用法应该是这样的:

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

这避免了冲突