Angenommen, ich habe zwei Entitäten: Gruppe und Benutzer. Jeder Benutzer kann Mitglied vieler Gruppen sein und jede Gruppe kann viele Benutzer haben.
@Entity
public class User {
@ManyToMany
Set<Group> groups;
//...
}
@Entity
public class Group {
@ManyToMany(mappedBy="groups")
Set<User> users;
//...
}
Jetzt möchte ich eine Gruppe entfernen (sagen wir, sie hat viele Mitglieder).
Das Problem ist, dass der JPA-Anbieter (in meinem Fall Hibernate) beim Aufrufen von EntityManager.remove () in einer Gruppe keine Zeilen aus der Join-Tabelle entfernt und der Löschvorgang aufgrund von Fremdschlüsseleinschränkungen fehlschlägt. Das Aufrufen von remove () für den Benutzer funktioniert einwandfrei (ich denke, dies hat etwas mit dem Besitz der Seite der Beziehung zu tun).
Wie kann ich in diesem Fall eine Gruppe entfernen?
Die einzige Möglichkeit, die ich finden könnte, besteht darin, alle Benutzer in der Gruppe zu laden und dann für jeden Benutzer die aktuelle Gruppe aus seinen Gruppen zu entfernen und den Benutzer zu aktualisieren. Es erscheint mir jedoch lächerlich, bei jedem Benutzer aus der Gruppe update () aufzurufen, um diese Gruppe löschen zu können.
Folgendes funktioniert für mich. Fügen Sie der Entität, die nicht Eigentümer der Beziehung ist, die folgende Methode hinzu (Gruppe)
Beachten Sie, dass die Gruppe über eine aktualisierte Benutzerliste verfügen muss, damit dies funktioniert (was nicht automatisch erfolgt). Jedes Mal, wenn Sie der Gruppenliste in der Benutzerentität eine Gruppe hinzufügen, sollten Sie der Benutzerliste in der Gruppenentität einen Benutzer hinzufügen.
quelle
Ich habe eine mögliche Lösung gefunden, aber ... ich weiß nicht, ob es eine gute Lösung ist.
Ich habe es versucht und es funktioniert. Wenn Sie die Rolle löschen, werden auch die Beziehungen gelöscht (jedoch nicht die Berechtigungsentitäten), und wenn Sie die Berechtigung löschen, werden auch die Beziehungen zur Rolle gelöscht (jedoch nicht die Rolleninstanz). Wir ordnen jedoch zweimal eine unidirektionale Beziehung zu, und beide Entitäten sind Eigentümer der Beziehung. Könnte dies zu Problemen im Ruhezustand führen? Welche Art von Problemen?
Vielen Dank!
Der obige Code stammt aus einem anderen Beitrag .
quelle
Als Alternative zu JPA / Hibernate-Lösungen: Sie können eine CASCADE DELETE-Klausel in der Datenbankdefinition Ihres Foregin-Schlüssels in Ihrer Join-Tabelle verwenden, z. B. (Oracle-Syntax):
Auf diese Weise löscht das DBMS selbst automatisch die Zeile, die auf die Gruppe verweist, wenn Sie die Gruppe löschen. Und es funktioniert, ob das Löschen aus dem Ruhezustand / JPA, JDBC, manuell in der Datenbank oder auf andere Weise erfolgt.
Die Kaskadenlöschfunktion wird von allen wichtigen DBMS (Oracle, MySQL, SQL Server, PostgreSQL) unterstützt.
quelle
Für was es wert ist, verwende ich EclipseLink 2.3.2.v20111125-r10461 und wenn ich eine unidirektionale @ ManyToMany-Beziehung habe, beobachte ich das von Ihnen beschriebene Problem. Wenn ich es jedoch in eine bidirektionale @ ManyToMany-Beziehung ändere, kann ich eine Entität von der nicht besitzenden Seite löschen und die JOIN-Tabelle wird entsprechend aktualisiert. Dies ist alles ohne die Verwendung von Kaskadenattributen.
quelle
Dies ist eine gute Lösung. Das Beste ist auf der SQL-Seite - die Feinabstimmung auf jede Ebene ist einfach.
Ich habe MySql und MySql Workbench verwendet, um beim Löschen für den erforderlichen Fremdschlüssel eine Kaskade zu erstellen.
quelle
Das funktioniert bei mir:
Markieren Sie auch die Methode @Transactional (org.springframework.transaction.annotation.Transactional). Dies führt den gesamten Prozess in einer Sitzung aus und spart Zeit.
quelle
Für meinen Fall habe ich das mappedBy gelöscht und Tabellen wie folgt verbunden:
quelle
Dies funktioniert bei einem ähnlichen Problem, bei dem ich den Benutzer aufgrund der Referenz nicht löschen konnte. Danke dir
quelle