我收到错误:
请勿使用cascade =“all-delete-orphan”
更改对集合的引用
尝试以下操作时:
beginTx();
Parent parent = new Parent();
Child child = new Child();
parent.addChild(child);
getSession().save(parent);
commitTx();
closeSession();
beginTx();
//id is the primary key
child.setID(null);
getSession().update(child);
commitTx();
closeSession();
父母与子女在one-to-many
之间与cascade ='all-delete-orphan
'相关。
class Parent {
Set child;
}
<set name="child" table="Child" cascade="all-delete-orphan" inverse="true">
<key column="FK"></key>
<one-to-many class="Child"/>
</set>
知道为什么会抛出这个异常吗? 为什么即使实体处于分离状态,主键上的null也会导致此异常?
答案 0 :(得分:7)
如果您加载具有cascade=all-delete-orphan
集合的实体,则会发生此异常,然后删除对该集合的引用。
请勿替换此集合。始终使用collection.clear()
删除所有关联的子条目,以便孤立删除算法可以检测到更改。如果你想删除任何特定的孩子,你只需要从集合中删除它。一旦将其从集合中删除,它将被视为孤儿并将被删除。
答案 1 :(得分:2)
用于例外不要使用cascade =&#34; all-delete-orphan&#34;更改对集合的引用。使用child.setID(null);
更改ID会导致异常。
hibernate使用PersistentSet
来执行异常检查,所以你可以这样做:
child.setID(null);
parent.child=new HashSet(parent.child)
使用HashSet替换PersistentSet
答案 2 :(得分:1)
这是因为关闭交易不会关闭当前会话。这意味着child
仍然是当前会话的一部分,Hibernate仍然认为它是同一个孩子,并且会尝试在数据库上清空它的id
。
如果您想让child
对象出现瞬态,请在其上使用evict()
。