2009-12-03 42 views
1

当我将收集设置为空时,尽管删除收集时会删除孤立,但Hibernate不会删除孤儿。我有以下关联。休眠DELETE_ORPHAN级联类型不会删除收集设置为空时的孤儿

D - entity, contains a single embedded E 
E - embedded object, contains one to many relationship with F (cascade type all,DELETE_ORPHAN) 
F - entity, contains a collection of Strings 

注意,由于E被嵌入d,数据库中的E具有外侧D.因此我将提到d/E作为一个单元没有身份。另请注意,F包含一组字符串。由于hibernate的限制,这意味着F必须是实体,而不是可嵌入的值类型。 E中F的集合的级联类型包括all和DELETE_ORPHAN。

如果我想从D/E中删除F的集合,我可以明确地清除集合中的所有F,就像这样。

D d = //get a reference to a D 
E e = d.getE(); 
Set<F> fs = e.getFs(); 
fs.clear(); 
//... update d in the session 

这正确删除从F表关于d/E为Fs的所有数据库行,并从d/E到F相关行连接表,因为我期望的那样。但是,假设我想将F的集合设置为null,就像这样。

D d = //get a reference to a D 
E e = d.getE(); 
e.setFs(null); 
//... update d in the session 

虽然这会删除连接表d/E和F之间的关系,它不会删除了从F表关于d/E在FS的数据库行。那些数据库行现在是孤立的。

是否有一个休眠设置,允许将F的集合设置为null并让hibernate意识到原始集合中的所有F现在都是孤立的?

回答

4

你认为Hibernate会如何知道它应该删除你所有的F实体?

Transitive persistence要求可达性;为了让Hibernate知道所有(或某些)集合元素已被删除,它将用自己的集合类替换它们来跟踪这些更改。

您应该从不一旦创建/实例化,删除对集合的引用;如果你这样做了,那么这些改变会丢失(无论是在幕后默默无闻,或者在某些情况下你可能会遇到异常)。

使用clear()是告诉Hibernate你想删除集合元素的正确方法。

+0

感谢您的信息!现在,当E被设置为空时,F实体也不会被删除。这是否也是由于缺乏可达性?当E被设置为空时,是否有更好的方法来构造这些关联来删除F孤儿? – 2009-12-04 17:10:22

+0

如果'E'确实嵌入了**,将它设置为null与从Hibernate的角度看,完全相同,因为将'F'的集合设置为null(参见Hibernate文档中的组件章节)。如果'E'是一个实体,你必须明确地删除它,或者如果它本身就是'D'上的一个集合元素,那么可以将它从集合中删除,假设它是cascade = all-delete-orphan。 – ChssPly76 2009-12-04 18:39:27