我在通过级联删除 - 孤儿删除另一个实体时遇到问题。 当我清除相关的集合集合时它会起作用,但是当我将集合集合置为空时它不起作用。 让我详细解释一下。 配置代码段:
<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();
如果我从数据库重新加载cat项目,它仍然包含BLA项目,并且Hibernate没有生成删除语句:( .. 为什么不呢?......或者这是一个错误?我使用的是3.6.0.Final。
答案 0 :(得分:2)
我认为它是因为hibernate使用自己的集合实现(这就是为什么文档说你必须将集合声明为接口而不是实现),并且集合实现遵循传递持久性设置的语义。所以,当你做的时候
cats.getBla().clear()
getBla()部分是hibernate集合实现,它知道在调用clear()时从会话中删除子节点。
当你这样做时
cats.setBla(null);
您尚未删除集合,您已将父集合对集合的引用更改为null。该集合可能仍然存在于会话中。
答案 1 :(得分:0)
在Hibernate的第5版中,问题非常相似,但抛出异常:“拥有实体实例不再引用具有cascade =”all-delete-orphan“的集合”。要解决这个问题,我必须从空值切换到空集合。
Hibernate中的问题发布在这里:https://hibernate.atlassian.net/browse/HHH-9940