2016-11-04 6 views
0

Ich habe ein Problem und ich konnte keine Lösung finden. Ich habe bidirektional viel zu viele Anotationen. Ich habe diese Tabellen in DB (MariaDB):JPA ManyToMany bidirektionale einfügen

  • Artikel
  • Abschnitt
  • item_section

Artikel gehört:

@ManyToMany(fetch = FetchType.LAZY) 
@JoinTable(name = "item_section", 
     joinColumns = { 
      @JoinColumn(name = "item", nullable = false, updatable = false)}, 
     inverseJoinColumns = { 
      @JoinColumn(name = "section", nullable = false, updatable = false)}) 
private Set<Section> sections; 

Abschnitt Teil:

@ManyToMany(fetch = FetchType.EAGER, mappedBy = "sections") 
private Set<Item> items; 

PROBLEM:

ich zunächst einige Abschnitte erstellen. Als ich möchte Artikel "innerhalb" dieses Abschnitts erstellen. Also erstelle ich eine Instanz von Item und füge einige existierende Sektionen in set ein (Sektionen, die ich von DAO bekomme). Wenn ich den Artikel persistiere, werden Datensätze in den Tabellen item und item_section erstellt. Aber wenn ich einige der betroffenen Abschnitt von DAO und iterate thru Elemente bekommen Datenbank Änderungen sind nicht hier, Sections Instanzen sind im gleichen Zustand wie vor dem Einfügen.

Was habe ich falsch gemacht?

PS: Ich benutze Eclipse, aber ich glaube nicht, es

SOLUTION

Als @ Chris i bestehen utimately bereits nur eine Seite der Richtung existieren genannt sagte interessant ist. Es wurden keine Kaskaden definiert, so dass persistente Sektionen weder persistiert noch verschmelzen. So beste Lösung für meine staless und JTA-Lösung war die Verwendung merge statt auf Artikel anhalten und MERGE Kaskade Abschnitte Sammlung ...

Vielen Dank allen, die kamen zu helfen, vor allem aber zu @ Chris

+1

Haben Sie sich bemüht, beide Seiten der Beziehung zu setzen? Da Sie keinen Persistenz-Code angeben, ist kein weiterer Kommentar möglich. –

+0

Dank @NeilStockton, aber welche Persistenz Code möchten Sie? Ich mache einfach entityManager.persist (Element), wobei EntityManager eine Instanz von EntityManager und Element eine Instanz von Item ist. Was meinen Sie mit "_ \t Haben Sie sich bemüht, beide Seiten der Beziehung zu setzen? _" Ich habe beide Arent ich gesetzt? – Majlanky

+0

Niemand kann sagen, ob Sie beide Seiten der Beziehung (in den Objekten, die beibehalten werden sollen) festlegen, da Sie den Persistenzcode nicht veröffentlichen (Sie haben nur die Klassen veröffentlicht). Du rufst also weiter auf "Gegenstand" ... und hast du den anderen Gegenstand (Abschnitt) angerufen? Niemand kann kommentieren, bis du es tust –

Antwort

0

Es scheint, Sie sind fehlt das Attribut cascade = CascadeType.ALL. Sie sollten versuchen,

@ManyToMany(fetch = FetchType.LAZY) 
@JoinTable(name = "item_section", 
     joinColumns = { 
      @JoinColumn(name = "item", nullable = false, updatable = false)}, 
     inverseJoinColumns = { 
      @JoinColumn(name = "section", nullable = false, updatable = false)}) 
private Set<Section> sections; 

zu

@ManyToMany(cascade=CascadeType.ALL,fetch = FetchType.LAZY) 
@JoinTable(name = "item_section", 
     joinColumns = { 
      @JoinColumn(name = "item", nullable = false, updatable = false)}, 
     inverseJoinColumns = { 
      @JoinColumn(name = "section", nullable = false, updatable = false)}) 
private Set<Section> sections; 

dann zu ändern, es funktioniert normal.

fand ich diesen Fehler über das Tutorial Hibernate Many-To-Many Bidirectional Mapping Example

Hope this Hilfe

+0

Ich kann das nicht tun. Wenn ich diese Kaskade als Persistenz hinzufüge, wird die Operation auch für alle betroffenen Sektionen aufgerufen. Also ich habe jetzt Doppelzüngigkeit in DB. Es ist der Grund, warum ich alles cascased entfernte. Ich möchte keine Kaskade machen. Ich möchte betroffene Abschnitte aktualisiert nach dem Einfügen in Elementtabelle. Oder irre ich mich irgendwann? – Majlanky

+0

Sie meinen, betroffene Abschnitte, die nach dem Einfügen aktualisiert wurden, haben keine Verweise auf Elemente, richtig? Tatsächlich betroffene Abschnitte haben immer noch Referenzen auf sie. Sie verwenden jedoch FetchType.EAGER, damit Sie betroffene Abschnitte mit derselben Sitzung erhalten, wenn Sie Element persisten, dann haben sie keine Referenz. Sie sollten sie mit anderen Sitzung erhalten, dieses Problem ist gelöst. Oder Sie können EAGER zu LAZY ersetzen, dann funktioniert alles gut. –

+1

Noch eine Sache, für ManyToMany Beziehung empfehle ich dringend, dass Sie LAZY anstelle von EAGER –

0

Problem in möglicherweise falsch von Eclipse gemeinsam genutzten Cache verwendet, die standardmäßig aktiviert ist. Versuchen Sie es zu deaktivieren, indem das Hinzufügen in persistence.xml folgenden:

<shared-cache-mode>NONE</shared-cache-mode>

Wenn Sie anhalten oder fusionieren Section Anbieter spült es zu Datenbank und fügen Sie Section Instanz gemeinsam genutzten Cache, so dass es aus dem Speicher auf der nächsten Anfragen abgerufen werden können.Wenn Sie fortfahren Item aktualisieren Sie nur eine Seite der Beziehung, aber die andere Seite wird nicht aktualisiert und wird nicht mehr synchron. In JPA wie in Java im Allgemeinen liegt es in der Verantwortung der Anwendung oder des Objektmodells, Beziehungen aufrechtzuerhalten. Wenn Ihre Anwendung zu einer Seite einer Beziehung hinzugefügt wird, muss sie zur anderen Seite hinzugefügt werden. Lesen Sie mehr über das Caching im Bi-Direction-Mapping in this article. Ich kann folgende Lösungen des Problems bieten:

  1. Disable Cache für die gesamte Anwendung in persistence.xml
  2. manuell Section in DAO aktualisieren, bevor es an Benutzer
  3. Verwenden Cache korrekt durch die Aktualisierung beiden Seiten der Beziehung abrufen:
Verwandte Themen