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

use*_*052 8 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();
Run Code Online (Sandbox Code Playgroud)

父母和孩子通过one-to-manycascade =' 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>
Run Code Online (Sandbox Code Playgroud)

知道为什么会抛出这个异常吗?为什么即使实体处于分离状态,在主键上设置null也会导致此异常?

Deb*_*kia 7

如果加载具有集合的实体,则会发生此异常cascade=all-delete-orphan,然后删除对集合的引用.

不要替换此集合.始终用于collection.clear()删除所有关联的子条目,以便孤立删除算法可以检测到更改.如果你想删除任何特定的孩子,你只需要从集合中删除它.从集合中删除后,它将被视为孤儿并将被删除.

  • 但是,如果你看一下片段,我就没有替换过这个集合了.我只是在主键上设置null. (2认同)
  • 怎么可能呢?我假设这个.如果我错了,请更正我.使对象瞬态`:Hibernate将它视为一个新的孩子并将尝试坚持它.它与向集合中添加新子项相同.您希望将其设置为瞬态,但您不希望将其从集合中删除.它就像你想要改变持久对象的ID一样.但是主键的定义说它不仅是唯一的,而且在整个生命周期中也是不变的.Hibernate不支持更改标识符值.这可能是此例外的原因. (2认同)
  • 但是我还是很困惑!无论如何,如果要添加一个新的孩子,请创建并添加一个孩子。如果要更新现有的,则只需更新其属性。如果要删除一个,只需将其从集合中删除即可。在`commitTx()`期间,更改将与DB同步。我看不到需要使持久对象成为临时对象,然后再次将其添加回集合中。 (2认同)