Frage

Ich habe zwei Entitätsklassen in der folgenden Art und Weise kommentierten

@Entity
class A {
   @ManyToMany(mappedBy="A", cascade=CascadeType.ALL)
   private List<B> b;
 ..
}

@Entity
class B {
   @ManyToMany(cascade=CascadeType.ALL)
   private List<A> a;
 ..
}

Wenn ich eine Instanz der Klasse ‚B‘ speichern, werden die Beziehungen in der Datenbank gespeichert und der Getter in der Klasse ‚A‘ wird die richtige Teilmenge von B zurück. Allerdings, wenn ich Änderungen an der Liste der Hotels in ‚A‘ zu machen, werden die Änderungen nicht in der Datenbank gespeichert?

Meine Frage ist, wie kann ich es machen, so dass Änderungen in jeder Klasse „kaskadiert“ auf der anderen Klasse sind?

EDIT:. Ich habe versucht, verschiedene Varianten der mappedBy-Parameter zu entfernen und eine JoinTable (und Spalten) definieren, aber ich habe es nicht gelungen, die richtige Kombination finden

War es hilfreich?

Lösung

Die kürzeste Antwort scheint nicht zu sein und es macht Sinn. In einem bidirektionalen many-to-many-Verband muss ein Seite Master sein und verwendet wird, um Änderungen an den zugrunde liegenden Join-Tabelle zu beharren. Als JPA nicht beide Seiten des Vereins halten, könnte man mit einer Speicher Situation am Ende, die einmal nicht neu geladen in der Datenbank gespeichert werden. Beispiel:

A a1 = new A();
A a2 = new A();
B b = new B();
a1.getB().add(b);
b.getA().add(a2);

Wenn dieser Zustand beibehalten werden könnte, würden Sie mit den folgenden Einträgen in der Join-Tabelle am Ende:

a1_id, b_id
a2_id, b_id

Aber beim Laden, wie würde JPA wissen, dass Sie sollten nur b etwa a2 und nicht a1 wissen lassen? und was ist a2, die über b nicht wissen sollte?

Dies ist, warum Sie die bidirektionale Assoziation zu halten haben sich (und das obige Beispiel unmöglich zu erreichen, auch in Erinnerung machen) und JPA wird bestehen bleiben nur basierend auf dem Zustand von einer Seite davon.

Andere Tipps

Haben Sie die inverse angegebenen Spalten mit?

@Entity
class A {
   @ManyToMany(mappedBy="A", cascade=CascadeType.ALL)
   private List <B> b;
   ..
}

@Entity 
class B { 
   @ManyToMany 
   @JoinTable (
       name="A_B",
       joinColumns = {@JoinColumn(name="A_ID")},
       inverseJoinColumns = {@JoinColumn(name="B_ID")}
   )
   private List<A> a; 
   .. 
} 

Das ist unter der Annahme einer Tabelle A_B mit Spalten A_ID und B_ID genannt verbinden.

  

Wie die Beziehung ist bidirektional, um das Anwendungs-Updates   eine Seite der Beziehung, sollte die andere Seite auch aktualisiert werden,   und synchron sein. In JPA, wie in Java im Allgemeinen es ist der   Verantwortlichkeit der Anwendung oder dem Objektmodell zu halten,   Beziehungen. Wenn Ihre Anwendung fügt einer auf einer Seite   Beziehung, dann muss es auf die andere Seite hinzuzufügen.

     

Dies kann durch Hinzufügen oder Set-Methoden im Objektmodell gelöst werden   dass beide Seiten der Beziehungen handhaben, so dass der Anwendungscode   braucht nicht darum zu kümmern. Es gibt zwei Möglichkeiten, um dies zu realisieren,   Sie können entweder nur die Beziehung Wartungscode zu einer Seite hinzufügen   die Beziehung, und nur die von einer Seite setter verwenden (wie beispielsweise   so dass die andere Seite geschützt) oder fügen Sie es beiden Seiten und gewährleisten   Sie eine Endlosschleife vermeiden.

Quelle: OneToMany # Getters_and_Setters

Haben Sie versucht, den mappedBy Parameter auf die A-Feld in der Klasse B Hinzufügen wie so

@Entity
class B {
   @ManyToMany(cascade=CascadeType.ALL, mappedBy = "b")
   private List<A> a;
 ..
}

Vielleicht gibt es einen kleinen Fehler in a_m Antwort. Meiner Meinung nach sollte es sein:

   @Entity
   class B { 
   @ManyToMany 
   @JoinTable (
       name="A_B",
       joinColumns = {@JoinColumn(name="B_ID")},
       inverseJoinColumns = {@JoinColumn(name="A_ID")}
   )
   private List a; 
   .. 
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top