2012-02-24 105 views
15

在我的應用程序中,hibernate操作是這樣的。 應用程序使用來自請求的新值更新父實體,並刪除所有現有的(先前插入的)子實體並插入新的子記錄。擁有cascade =「all-delete-orphan」的集合不再被擁有實體實例引用

爲此,我使用hibernates DELETE_ORPHAN,如下所示。

當我這樣做,我發現了以下異常:

org.hibernate.HibernateException:與 級聯=「全刪除,孤兒」,由擁有 不再引用集合實體實例:com.childs

我看到類似的線程與問題,我試圖在這些線程appy解決方案。但是,這並不能工作

我父實體

public class Parent implements Serializable { 

      @Column(name = "PARENT_ID") 
      @Basic(fetch = FetchType.EAGER) 
      @Id 
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq") 
      @SequenceGenerator(name = "seq", sequenceName = "seq") 
      private Integer parentId; //primary key of parent 

      ....... 
      ........ 

      //mapping to child entity 
      @OneToMany(mappedBy = "parent", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) 
      @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 
      private Set<Child> childs; 

      ................ 
      ............... 

} 

兒童實體有組合鍵和具有PK實體呈現出以下

public class ChildPK implements Serializable { 

    /** The Constant serialVersionUID. */ 
    private static final long serialVersionUID = -447592368963477750L; 

    /** . */ 
    @ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) 
    @JoinColumns({ @JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID") }) 
    @Id 
    private Parent parent; 

    /**. */ 

    @Column(name = "CHILD_ID") 
    @Basic(fetch = FetchType.EAGER) 
    @Id 
    @GenericGenerator(name="child_seq", strategy="com.DB2Dialect") 
    @GeneratedValue(generator="child_seq") 
    private Integer childId; 

} 

child entity goes like this: 


public class Child implements Serializable { 

    /** The Constant serialVersionUID. */ 
    private static final long serialVersionUID = 185670997643552301L; 

    /** The pol cntct id. */ 
    @Column(name = "CHILD_ID") 
    @Basic(fetch = FetchType.EAGER) 
    @Id 
    private Integer childId; 

    @ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) 
    @JoinColumns({ @JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID") }) 
    @Id 
    private Parent parent; 

} 

Java代碼

................... 
    .............. 
    parent.getChild().clear(); 
    Child child = new Child(); 
    parent.setChild(child); 

這裏可能是錯的。
在此先感謝...

回答

49

您最後一段Java代碼不能編譯。我想它看起來像

parent.getChilds().clear(); // note: you should name it children rather than childs 
parent.setChilds(someNewSetOfChildren): 

不要做最後的指令。相反,通過一個又一個更換設置,清除設置和新的孩子加入到清零設置:

parent.clearChildren(); 
parent.addChildren(someNewSetOfChildren); 

其中該方法被定義爲:

public void clearChildren() { 
    this.children.clear(); 
} 

public void addChildren(Collection<Child> children) { 
    this.children.addAll(children); 
} 

的setChildren方法應完全清除掉,或者應該用下面的實現來代替:

public void setChildren(Collection<Child> children) { 
    this.children.clear(); 
    this.children.addAll(children); 
} 
+0

對於@JBNizet我有類似的問題,我應用了您的解決方案。實際上,從你指出的兩個解決方案中,我使用了後者(在setter方法中,我清除了children collection - this.children.clear() - 並添加了新的children - this.children.addAll(children))。此更改並未解決我的問題。我仍然得到「具有cascade =」all-delete-orphan的集合「不再被擁有實體實例」異常引用「。你知道爲什麼嗎?非常感謝你! – ovdsrn 2012-12-12 10:37:08

+0

不,我不知道。你可以問一個問題,顯示你的代碼,完整的堆棧跟蹤等。 – 2012-12-12 15:26:55

+1

也許在'setChildren'應該加上空檢查'if(children!= null){this.children.addAll(children);}' – lolotron 2016-03-24 12:40:51

9

它對我有用。

  1. 清除了我所有的子實體。
  2. 而不是將新的子實體設置爲我的父對象,我已經使用addAll方法來添加新的子實體。

    parent.getChildren().clear(); 
    parent.getChildren().addAll(newChildrenList); 
    
    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, 
          cascade = CascadeType.ALL, orphanRemoval = true) 
    
    public Set<Children> getChildren() { 
        return this.children; 
    } 
    
4

,而不是setChilds使用addAll

從此,

parent.getChilds().clear(); 
    parent.setChilds(newChilds); 

parent.getChilds().clear(); 
    parent.getChilds().addAll(newChilds); 
+0

在哪裏應該添加?在父實體中還是在子實體中?父實體中的 – 2017-10-13 06:07:01

+0

添加所有子實體 – mathi 2017-10-16 06:08:43

5

我面臨着同樣的問題,並把它解決了,如下所示:

1-添加{CascadeType.ALL},在該元素的所有實體童車所有@OneToMany註解orphanRemoval =真

2-檢查hashCode()方法equalls()這些實體的有時他們有誤差修改

3-不要使用parent.setChilds(newChilds);由於發動機會要求缺少參考孩子的,而是用改用

parent.getChilds().clear(); 
parent.getChilds().add(Child); 

parent.getChilds().addAll(Childs); 

這些步驟解決了我的問題經過4小時的研究

相關問題