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); . . }
这避免了冲突