不要使用cascade =“all-delete-orphan”更改对集合的引用

时间:2013-09-20 06:56:04

标签: java hibernate hibernate-onetomany

我收到错误:

  

请勿使用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也会导致此异常?

3 个答案:

答案 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()