Java 找到对集合 org.hibernate.HibernateException 的共享引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1692871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Found shared references to a collection org.hibernate.HibernateException
提问by nightingale2k1
I got this error message:
我收到此错误消息:
error: Found shared references to a collection: Person.relatedPersons
错误:找到对集合的共享引用:Person.relatedPersons
When I tried to execute addToRelatedPersons(anotherPerson)
:
当我尝试执行时addToRelatedPersons(anotherPerson)
:
person.addToRelatedPersons(anotherPerson);
anotherPerson.addToRelatedPersons(person);
anotherPerson.save();
person.save();
My domain:
我的域名:
Person {
static hasMany = [relatedPersons:Person];
}
any idea why this happens ?
知道为什么会这样吗?
采纳答案by ChssPly76
Hibernate shows this error when you attempt to persist more than one entity instance sharing the samecollection reference (i.e. the collection identity in contrast with collection equality).
当您尝试保留多个共享相同集合引用的实体实例(即集合标识与集合相等性相反)时,Hibernate 会显示此错误。
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?
请注意,这意味着同样的集合,而不是集合元素-换句话说,relatedPersons
在两个person
和anotherPerson
必须相同。也许您正在加载实体后重置该集合?或者您已经使用相同的集合实例初始化了两个引用?
回答by 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.
我有同样的问题。就我而言,问题是有人使用 BeanUtils 将一个实体的属性复制到另一个实体,因此我们最终有两个实体引用同一个集合。
Given that I spent some time investigating this issue, I would recommend the following checklist:
鉴于我花了一些时间调查这个问题,我会推荐以下清单:
Look for scenarios like
entity1.setCollection(entity2.getCollection())
andgetCollection
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)
.
寻找类似的场景
entity1.setCollection(entity2.getCollection())
并getCollection
返回对集合的内部引用(如果 getCollection() 返回集合的新实例,则您无需担心)。看看是否
clone()
已经正确实施。寻找
BeanUtils.copyProperties(entity1, entity2)
.
回答by Mirimas
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);
回答by John Lopez
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:
就我而言,我是从其他类中复制和粘贴代码,所以我没有注意到 getter 代码写得不好:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "credito")
public Set getConceptoses() {
return this.letrases;
}
public void setConceptoses(Set conceptoses) {
this.conceptoses = conceptoses;
}
All references conceptosesbut if you look at the get says letrases
所有参考文献都是概念性的,但如果你看一下 get 说letrases
回答by Diego87
Reading online the cause of this error can be also an hibernate bug, as workaroundthat 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
我的问题等于 100%:http: //www.progtown.com/topic128073-hibernate-many-to-many-on-two-tables.html
回答by 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.
我也遇到了同样的问题,有人用过BeanUtils.copyProperties(source, target)
。这里的源和目标都使用相同的集合作为属性。
So i just used the deep copy as below..
所以我只是使用了如下的深拷贝..
How to Clone Collection in Java - Deep copy of ArrayList and HashSet
回答by 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.
这里的用户和foo.getUser()
共享相同的引用。但是保存这两个引用会产生冲突。
The proper usage should be:
正确的用法应该是:
class Foo1 {
List<User> user = new ArrayList<>();
user.addAll(foo.getUser);
}
This avoids the conflict.
这样就避免了冲突。
回答by 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.
我在我的应用程序中遇到了类似的异常。在查看堆栈跟踪后,很明显异常是在FlushEntityEventListener
类中抛出的。
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.
在 Hibernate 4.3.7 中,MSLocalSessionFactory
bean 不再支持该eventListeners
属性。因此,必须从单个 Hibernate 会话 bean 中显式获取服务注册表,然后设置所需的自定义事件侦听器。
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.
在添加自定义事件侦听器的过程中,我们需要确保从相应的 Hibernate 会话中删除相应的默认事件侦听器。
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.
如果未删除默认事件侦听器,则会出现针对同一事件注册的两个事件侦听器的情况。在这种情况下,在迭代这些侦听器时,针对第一个侦听器,会话中的任何集合都将被标记为已到达,而针对第二个侦听器处理相同的集合时,将抛出此 Hibernate 异常。
So, make sure that when registering custom listeners corresponding default listeners are removed from registry.
因此,请确保在注册自定义侦听器时从注册表中删除相应的默认侦听器。
回答by simibac
My problem was that I had setup an @ManyToOne
relationship. Maybe if the answers above don't fix your problem you might want to check the relationship that was mentioned in the error message.
我的问题是我已经建立了@ManyToOne
关系。也许如果上面的答案不能解决您的问题,您可能需要检查错误消息中提到的关系。