【问题标题】:Don't change the reference to a collection with cascade="all-delete-orphan"不要使用 cascade="all-delete-orphan" 更改对集合的引用
【发布时间】:2013-09-25 11:31:17
【问题描述】:

我收到一个错误:

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

【问题讨论】:

  • 它是针对哪个语句抛出的?是在child.setID(null);这一行吗?
  • childCategory 是什么?你想通过调用child.setID(null); 来达到什么目的?
  • @debojit :它的发生是因为 child.setID(null)
  • @user2599052,通过调用child.setID(null);,您是否试图删除子集中的特定条目?

标签: java hibernate hibernate-onetomany


【解决方案1】:

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

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

【讨论】:

  • 但是如果你查看sn-p,我没有在哪里替换集合。我只是在主键上设置 null。
  • 这就是为什么我以“通常会发生此异常”开始我的 ans .. 但是您为什么在子实体的主键上设置 null ?
  • 目的是使对象瞬态,而不是通过从集合中删除来做到这一点。
  • 这怎么可能?我假设这个。如果我错了,请纠正我。make the object transient:Hibernate 会将它视为一个新的孩子,并会尝试坚持下去。这与向集合中添加一个新孩子相同。您想让它成为瞬态的,但又不想将其从集合中移除。就像您要更改持久对象的 ID。但是主键的定义表明它不仅是唯一的,而且在整个行的生命周期中都是不变的。 Hibernate 不支持更改标识符值。这可能是导致此异常的原因。
  • 但我还是很困惑!!无论如何,如果您想添加一个新孩子,请创建并添加一个。如果你想更新一个现有的,你只需要更新它的属性。如果您想删除一个,只需将其从集合中删除即可。在commitTx() 期间,更改将与 DB 同步。我认为不需要使持久对象瞬态然后再次将其添加回集合中。
【解决方案2】:

对于异常不要更改对具有 cascade="all-delete-orphan" 的集合的引用。您使用 child.setID(null); 更改 ID 会导致异常。

hibernate 使用PersistentSet 执行异常检查,所以你可以这样做:

child.setID(null);
parent.child=new HashSet(parent.child)

用HashSet代替PersistentSet

【讨论】:

    【解决方案3】:

    这是因为关闭事务不会关闭当前会话。这意味着child 仍然是当前会话的一部分,Hibernate 仍然会认为它是同一个孩子,并会尝试在 DB 上取消其 id

    如果你想让child 对象瞬态,你应该在它上面使用evict()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-11
      • 2022-06-13
      • 2011-08-13
      • 2012-03-14
      • 2018-03-06
      相关资源
      最近更新 更多