2016-07-12 10 views
0

Sagen wir, ich habe 3 Arten von Objekten - Eltern-, Kind- und ChildAttrHibernate - Übertragen von einer Colleciton von Objekten von einem übergeordneten Objekt zu einem anderen

Mein Ziel ist es, eine Untergruppe der Kinder von einem Elternteil auf einen anderen mit Hibernate zu übertragen (3.2.5).

Objekte werden als solche strukturiert:

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; 
    } 
} 

Nun sage ich einige Client-Code ausführen, die eine Untergruppe von Eltern nimmt A Child-Objekte und verschiebt sie in Mutter 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. 

Ich erhalte eine Fehlermeldung beim Versuch geworfen parentB zu speichern.

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

Die Anwendung scheint derzeit zu funktionieren, funktioniert in mehreren Sitzungen - z. - Ein Benutzer kommt mit und entfernt die Gruppe von Kindern, die er später zu einem anderen Elternteil hinzufügt. Außerdem verstehe ich nicht wirklich, warum es mehrere Versionen dieser Attributliste instanziiert, wenn es wirklich nur eins sein sollte, selbst wenn sich das Elternteil ändert.

Was den oben genannten Fehler verursacht und wie ich um ihn erhalten?

+0

Versuchen Sie "@ Cascade" Annotationen zu löschen, nachdem Sie Kaskaden in '@ OneToMany' bereits überschritten haben, nachdem ich Kaskadenanmerkungen gelöscht habe. Mit Kaskaden habe ich" losgelöstes Entity bestanden, um persistiert zu werden ", nicht genau Ihr Fehler, aber Sie kann versuchen ... – csharpfolk

Antwort

1

Eine Daumenregel: sicherzustellen, dass die Objekte sind konsistent als Objektgraphen, bevor Sie versuchen, sie zu bestehen ... IOW Sie alle Kinder von den Eltern A sind zu entfernen und fügen sie zu parentB aber Sie haben nicht die übergeordnete aktualisiert Link für diese Kinder.

So würde ich vorschlagen, die folgende:

hinzufügen Methoden Parent:

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

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

Und dann auf Kind:

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

diese Weise, wenn Sie aus beiden Richtungen addieren Sie‘ Ich habe ein konsistentes Objektmodell, ohne dass der äußere Code die Details kennt.

Es macht mehr Sinn, von dem Elternteil zu entfernen ...

Also mit diesen Methoden versuchen.

+0

Dies hat den Trick, und ist eine saubere Lösung. – jiman

1

seens das ist, weil Ihre bidirektionale Beziehung (Eltern-Kinder). Wenn Sie das Kind ein Elternteil zum anderen entfernen/hinzufügen, sollten Sie die parent Referenz aktualisieren.

Verwandte Themen