2009-06-03 5 views
5

Mein Team hat zwei Klassen, User und Store, verwandt von JPA @ManyToMany Annotationen. Der entsprechende Code ist unten.JPA @ManyToMany Schreiben auf erstellen, aber nicht aktualisieren

Bei der Erstellung eines neuen User Objekts und der Einstellung seiner Filialen ist das Leben gut. Aber wir sehen ein unerwartetes Verhalten beim Versuch, Benutzerobjekte über unsere Struts 2/Spring-Webbenutzeroberfläche zu aktualisieren. (Diese Probleme treten nicht auf, wenn einfache automatische Integrationstests über JUnit ausgeführt werden).

Einfach gesagt, beim Speichern einer User, seine Stores Sammlung wird nicht aktualisiert - die Datenbank zeigt keine Änderungen, und das Neuladen des User Objekts in Frage zeigt, dass es einen unveränderten Satz von Speichern hat.

Die einzige Lösung, die wir für dieses Problem gefunden haben - und wir mögen diese Lösung nicht, es macht alle Entwickler in unserem Team ein bisschen mulmig - ist es, einen neuen Set von Store s dann zu erstellen tun Sie user.setStores(null), dann tun Sie user.setStores(stores).

Wir verwenden die OpenEntityManagerInViewFilter; Wir verwenden Hibernate als JPA-Anbieter. Wir verwenden Spring's JpaTransactionManager. Wir haben keine @Transactional Annotationen in unserem Code - und das Hinzufügen von ihnen bricht den vorhandenen Code aufgrund des anderswo beschriebenen Proxy-Verhaltens.

Jeder Einblick, den jemand geben könnte, wie wir dieses Problem in einer nicht-mulmigen Weise lösen könnten, ist willkommen.


relevante Teile User.java:

@ManyToMany 
@JoinTable(name = "company.user_store_access", 
     joinColumns = @JoinColumn(name = "userid"), 
     inverseJoinColumns = @JoinColumn(name = "storeid")) 
public Set<Store> getStores() { 
    return stores; 
} 

relevante Teile Store.java:

@ManyToMany(mappedBy = "stores") 
    public List<User> getUsers() { 
     return users; 
    } 

Relevante Teile UserDetailAction.java: (Durchreiche eine Schicht nach unten oder zwei, und dann :)

entity = getEntityManager().merge(entity); 
+1

Können Sie bitte die Codezeilen hinzufügen, in denen Sie Shops hinzufügen/ändern? –

Antwort

1

Bitte versuchen Sie die folgende Anmerkung in Ihrem Benutzerobjekt:

@ManyToMany(cascade = {CascadeType.ALL}) 
+0

Ich gebe das einen Versuch am Morgen - obwohl wir @ManyToMany hinzufügen (cascade = {CascadeType.PERSIST, CascadeType.MERGE}) bereits. –

6

Das Problem ist, dass Sie eine bidirektionale Beziehung haben, und in diesem Fall gibt es eine Einheit, die die andere steuert, und von Ihrem Abbilden des Controlling Einer ist der Store Entität und nicht der Benutzer, so würde das Hinzufügen eines Benutzers zu einem Geschäft funktionieren (da der Store derjenige ist, der steuert), aber das Hinzufügen eines Geschäfts zu einem Benutzer wird nicht.

versuchen Sie, die Situation zu invertieren, indem Sie das Benutzerobjekt zum Steuerelement machen, indem Sie die Annotation @ManyToMany (mappedBy = "users") auf die Methode getStores() setzen und getUsers() ändern.

Ich hoffe, es hat geholfen.

P.S. Die Entität, die die Beziehung steuert, ist immer diejenige, die das Attribut mappedBy nicht besitzt.

2

Ich habe gerade auf demselben Problem und Lösung auf einer anderen Seite gefunden.

Hier ist, was für mich gearbeitet hat

Aufruf getJpaTemplate(). Flush() vor merge Aufruf für mich gearbeitet hat.

Ich habe nicht den Grund, warum es funktioniert hat.

Verwandte Themen