2016-04-06 18 views
1

Ich verwende derzeit Hibernate in einem Projekt und ich habe Probleme beim Einrichten einer Viele zu viele Beziehung. Ich denke, mein Problem hängt mit den Cascade-Typen zusammen.Hibernate viele zu viele Kaskadenarten Problem

Das Szenario ist, wir haben eine Anzeige und jede Anzeige kann viele Tags haben, aber jedes Tag kann mit vielen Anzeigen verwandt sein. Die ManyToMany Anmerkung der Inserates Einheit ist:

@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH }) 
@JoinTable(name = "adMediaAdvertiserTag", 
     joinColumns = { @JoinColumn(name = "adMediaId") }, 
     inverseJoinColumns = { @JoinColumn(name = "advertiserTagId") }) 

Und das ManyToMany-Mapping auf dem Tag Entität:

@ManyToMany(mappedBy = "advertiserTags", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) 

Ich sehe zwei unterschiedliche Fehler abhängig von der Konfiguration der Kaskadentypen und wenn die Das Tag existiert bereits in der Datenbank.

Wenn der Kaskadentyp auf der Anzeige nicht enthält PERSIST und der Tag nicht schon existieren, dann bekommen wir diese Ausnahme:

TransientObjectException: object references an unsaved transient instance 

Und wenn der Kaskadentyp auf der Anzeige PERSIST enthält und die Tag bereits existiert, erhalten wir:

PersistentObjectException: detached entity passed to persist 

die einzige Art, wie ich diese Arbeits bekommen kann, ist nicht PERSIST als Kaskadentyp, sondern eine Schleife durch jeden Tag und an die Sitzung speichern.

Ist dies der richtige Ansatz? Gibt es eine Möglichkeit, dass der Winterschlaf für mich automatisch funktioniert?

Lassen Sie mich wissen, wenn dies nicht klar ist oder Sie weitere Informationen benötigen.

UPDATE

ich die Objekte speicherte einen Dienst verwenden, die die CrudRepository Aufgabe des spring speichert Methode verwendet. Es gibt eine Menge Code, also kann ich nicht alles posten.

Ich rufe derzeit keine Merge oder Persist-Methode für irgendein Objekt auf, das ich versuche zu speichern. Ich hatte den Eindruck, dass Hibernate so etwas für mich erledigen würde.

+0

So Sie sagen, dass einige der Tags bereits existieren könnten, da einige von ihnen neu sind und beibehalten werden müssen. Wenn ja, sollte es nicht ein Aufruf sein, zu "fusionieren" statt zu "persistieren"? –

+0

Ja, das ist richtig. Ich habe das versucht, aber wenn ein neues Tag hinzugefügt wird, gibt es TransientObjectException zurück: Objekt verweist auf eine nicht gespeicherte vorübergehende Instanz –

+0

Meinst du CascadeType oder die Methode, die zum Speichern des Objekts verwendet wird? –

Antwort

1

Können Sie bitte den Code hinzufügen, mit dem Sie Ihre Anzeigen- und Tag-Objekte beibehalten. Getestet habe ich mit dem folgenden Code (die ich ähnlich wie bei Ihnen glauben) und es funktioniert:

User user = new User(); 
Role role = new Role(); 
role.setId("TEST_ROLE"); 
user.getRoles().add(role); 

entityManager.persist(user); 

User user2 = new User(); 
user2.getRoles().add(role); 
entityManager.persist(user2); 
System.out.println(user2.getId()); 

in Benutzer ich habe:

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) 
@JoinTable(name = "user_roles", 
     joinColumns = {@JoinColumn(name = "user_id", nullable = false, updatable = true)}, 
     inverseJoinColumns = {@JoinColumn(name = "role_id", nullable = false, updatable = true)}) 
protected List<Role> roles = new ArrayList<>(); 

und in Rollen ich habe:

@ManyToMany(mappedBy="roles") 
protected List<User> users; 
+0

Vielen Dank für die Antwort, aber dies war eines der Szenarien, die ich erklärt habe, die nicht für das Szenario funktionierten, wenn wir ein existierendes Tag (oder eine Rolle in Ihrem Fall) haben. Ich werde die Frage mit etwas mehr Kontext aktualisieren. –

+0

Ich habe gerade den Aufruf der persist-Methode bemerkt, ist das für jedes neu erstellte Objekt erforderlich? –

+0

Ja, Sie müssen sicherstellen, dass in diesem Fall ein neuer Benutzer beibehalten wird, und das Role-Objekt wird aufgrund der Kaskade indirekt beibehalten. – Mustafa