2016-07-12 12 views
0

に1つの親オブジェクトからオブジェクトのCollecitonを転送することは、私は、オブジェクトの3種類を持っていると言う - 親、子、およびChildAttr休止状態 - 別

私の目標は、休止状態を使用して別の親から子供のサブセットを転送することです(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; 

アプリケーションは、現在、複数のセッションでは、この作業の罰金を行うようだ - 例えば - 一部のユーザーが子供のセットを取り出して削除し、その後しばらくして他の親に追加します。さらに、Parentが変更されたとしても、なぜそれが本当にただ一つであるべきなのかという理由で、その属性リストの複数のバージョンをインスタンス化するのは本当に理解できません。

上記のエラーの原因とは何ですか、どうすれば回避できますか?

+0

カスケードアノテーションを削除した後に、@ Cascadeアノテーションを削除しようとしました。カスケードアノテーションを削除した後、すでにカスケードを渡しています。カスケードでは、「分離されたエンティティは継承されました。試してみてください... – csharpfolk

答えて

1

親指からすべての子をすべて削除して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の参照を更新する必要があります。