2016-07-12 65 views
0

說我有3種類型的對象 - 父母,子女,和ChildAttr休眠 - Transfering對象的Colleciton從一個父對象到另一個

我的目標是兒童的一個子集從一個主機轉移到另一個使用Hibernate (3.2.5)。

對象的結構如下這樣:

public class Parent { 
    Set<Child> children; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "parent") 
    @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) 
    public Set<Child> getChildren() { 
    return this.children; 
    } 

    public void setChildren(Set<Child> children) { 
    this.children = children; 
    } 

} 

...

public class Child { 
    Set<ChildAttr> attributes; 
    Parent parent; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "child") 
    @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) 
    public Set<ChildAttr> getAttributes() { 
    return this.attributes; 
    } 

    public void setAttributes(Set<ChildAttr> attributes) { 
    this.attributes = attributes; 
    } 
} 

...

public class ChildAttr { 
    Child child; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "child_id", nullable = false) 
    public Child getChild() { 
    return this.child; 
    } 

    public void setChild(Child child) { 
    this.child = child; 
    } 
} 

現在說我跑了一些客戶端代碼,需要家長的一個子集A的子對象並將它們移到父B:

Set<Child> children = getChildrenToTransfer(transferCriteria, parentA); 

parentA.getChildren().removeAll(children); 
manager.saveOrUpdate(parentA); // method also calls flush(); 

parentB.getChildren().addAll(children); 
manager.saveOrUpdate(parentB); // error thrown here. 

嘗試保存parentB時,出現錯誤。

Found two representations of same collection: com.mycode.Child.attributes; 

該應用程序目前似乎在多個會話中正常工作 - 例如, - 某些用戶出現並刪除了一組孩子,然後一段時間後將其添加到其他父母。此外,我不明白爲什麼它實例化該屬性列表的多個版本時,它應該只是一個,即使父更改。

是什麼導致了上述錯誤,我該如何解決它?

+0

嘗試刪除'@ Cascade'註釋,您已在'@ OneToMany'中通過級聯註銷後,我刪除級聯註釋,您示例開始工作,級聯我得到「分離的實體傳遞給持久化」,不完全是你的錯誤,但你可能會嘗試... – csharpfolk

回答

1

一個經驗法則:確保對象在作爲對象圖形保持一致之前保持一致...如果您將所有孩子從父母A中刪除並將它們添加到parentB,但是您尚未更新父母這些孩子的鏈接。

所以我建議如下:

方法添加到父:

add(Child child) { 
    child.setParent0(this); 
    children.add(child); 
} 

remove(Child child) { 
    child.setParent0(null); 
    children.remove(child); 
} 

,然後在孩子:

setParent0(Parent parent) { 
    this.parent = parent; 
} 
setParent(Parent parent) { 
    parent.add(this); 
} 

當你從任何一個方向,你」添加這樣我們得到了一個一致的對象模型,沒有外部代碼知道細節。

它更有意義,從父刪除...

所以這些方法嘗試。

+0

這沒有竅門,而且是一個乾淨的解決方案。 – jiman

1

覺得這是因爲你的雙向關係(親子)。當您將孩子移除/添加到另一位家長時,您應該更新parent參考。

相關問題