6

我在通过级联删除孤儿删除另一个实体时遇到问题。它在我清除关联的集合集合时起作用,但在我将集合集合设为空时不起作用。让我详细解释一下。配置片段:

<class name="com.sample.CategoriesDefault" table="cats">
  <id name="id" column="id" type="string" length="40" access="property">
     <generator class="assigned" />
  </id>
  <version name="version" column="objVrs"  unsaved-value="negative"/>

 <set name="bla" lazy="false" cascade="all-delete-orphan" inverse="true">
      <key column="idCats" not-null="true"/>
       <one-to-many class="com.sample.BLA"/>
 </set>

<class name="com.sample.BLA" table="blaTEST">
   <id name="id" column="id" type="string" length="40" access="property">
     <generator class="assigned" />
   </id>
   <version name="version" column="objVrs"  unsaved-value="negative"/>
   <property name="bla" type="string" column="bla"/>
   <many-to-one name="parent" class="com.sample.CategoriesDefault" column="idCats" not-null="true"/>
</class>

我的示例代码:

Categories cats = new CategoriesDefault();
final Set<BLA> col = new HashSet<BLA>();
col.add(new BLA(cats));
cats.setBla(col);
cats.saveOrupdate(); // will update/insert it in the db.

以下工作正常,即:所有集合项都从数据库中移出。

cats.getBla().clear();
cats.saveOrUpdate();

我认为这是因为 Hibernate 的 PersistSet 在调用此方法时被标记为脏。

但是,以下内容与我想要/期望的效果不同。

cats.setBla(null);
cats.saveOrUpdate();

如果我从数据库重新加载猫项目,它仍然包含 BLA 项目,并且 Hibernate 没有生成删除语句:(.. 为什么不??...或者这是一个错误?我使用的是 3.6.0.Final。

4

2 回答 2

2

我认为这是因为 hibernate 使用它自己的集合实现(这就是为什么文档说你必须将集合声明为接口,而不是实现),并且集合实现遵循传递持久性设置的语义。所以,当你这样做

cats.getBla().clear()

getBla() 部分是休眠集合实现,它知道在调用 clear() 时从会话中删除子节点。

当你这样做

cats.setBla(null);

您还没有删除集合,您已将父级对集合的引用更改为 null。该集合可能仍存在于会话中。

于 2011-01-22T20:27:04.670 回答
0

在 Hibernate 的第 5 版中,问题非常相似,但会引发异常:“拥有的实体实例不再引用具有 cascade="all-delete-orphan" 的集合”。为了解决这个问题,我不得不从空值切换到空集合。

Hibernate 中的问题发布在这里:https ://hibernate.atlassian.net/browse/HHH-9940

于 2017-04-14T09:40:06.813 回答