2011-06-12 92 views
0

我有以下类别:如何更新hibernate上的集合?

class A { 
    Integer id; 

    @OneToMany(mappedBy="parent", fetch=FetchType.EAGER, cascade={CascadeType.ALL}) 
    Set<B> children; 
} 

class B { 
    Integer id; 

    @ManyToOne(fetch=FetchType.EAGER) 
    A parent; 
} 

在数据库中有数据,说有{B1,B2,B3}儿童A1。 当我尝试更新a1的孩子集{b4,b5}我最终在数据库中有b1..b5。 在我的代码中,我采取了预防措施,在子集上调用clear(),但它不影响数据库。

我应该迭代和呼吁session.delete(child) A的每个孩子?

谢谢,

回答

2

从Java EE 6(和Hibernate 3.5),你应该使用@OneToMany(...,orphanRemoval=true)

此前的Java EE 6/Hibernate的3.5,你可以使用org.hibernate.annotations.CascadeType.DELETE_ORPHAN,这是有利于增加的弃用3.5对JPA的孤儿删除。

+0

我正在使用hibernate 3.6.4,并且DELETE_ORPHAN显示为弃用。 – Dan 2011-06-13 17:55:09

+0

感谢您指出。 Javadocs表示已弃用弃用版本。使用@OneToOne(orphanRemoval = true)或@OneToMany(orphanRemoval = true)。我要更新答案以明确说明。 – 2011-06-13 17:59:29

0

问题是Cascade.All关于子项目。基本的问题是,即使你正在清除父对象上的集合,子对象将自己保存为拥有a1作为父对象。这意味着你需要清除双方的关系。有两条路线:

  1. 删除子项上的cascade.all,并让父对象管理整个关系。

  2. 通过清除子元素上的父元素或完全删除它们从会话中手动处理关系。在选择这条路线时,您需要非常明确地了解集合中每个元素的情况。

+0

试图从儿童方面删除级联,仍然同样的效果。以前的小孩不会被删除。任何想法为什么? – Dan 2011-06-13 05:17:26

+0

您是否尝试在从一侧删除级联之后进行清除()?如果这不起作用,那么最好的办法就是尝试第2条线路--Hibernate对于如何管理好多关系非常严格。 – Fourth 2011-06-13 11:27:04