JPA-Aktualisierung der Bidirektionalen Assoziation
Nehmen wir an, wir haben die folgenden Entitäten:
@Entity
public class Department {
@OneToMany(mappedBy="department")
private List<Employee> employees;
}
@Entity
public class Employee {
@ManyToOne
private Department department
}
Ist es verständlich auf ein update, das wir halten müssen, um beide Seiten der Beziehung wie folgt:
Employee emp = new Employee();
Department dep = new Department();
emp.setDepartment(dep);
dep.getEmployees().add(emp);
Alles gut bis jetzt. Die Frage ist, sollte ich mich bewerben merge-auf beiden Seiten, wie folgt, und ich vermeiden, dass die zweite Verschmelzung mit einer Kaskade?
entityManager.merge(emp);
entityManager.merge(dep);
Oder ist das Zusammenführen der besitzenden Seite genug? Auch sollten diese Zusammenführungen geschehen innerhalb einer Transaktion oder EJB? Oder tun es auf eine einfache controller-Methode mit getrennten Entitäten ist genug?
- Wenn Sie die Interaktion mit der Datenbank haben, sollten Sie innerhalb einer Transaktion. Das ist wahr, unabhängig davon, ob Sie mit JPA oder nicht. Es spielt keine Rolle, ob eine Transaktion explizit oder implizit gestartet, durch einen Aufruf einer EJB; beide werden die Arbeit tun.
- Was TomAnderson sagte, ist fast immer der Fall. Die Ausnahme ist, wenn Sie eine finden, und Sie finden mit einer Sperre andere als
LockModeType.NONE
.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie die cascade-annotation element zu verbreiten, die Wirkung einer operation verbundene Einrichtungen. Die cascade-Funktionalität wird typischerweise verwendet, in der Eltern-Kind-Beziehungen.
Den
merge
Vorgang wird kaskadiert auf Personen verwiesen wird, die von Beziehungen ausDepartment
wenn diese Beziehungen wurden kommentiert mit dercascade
element Wertcascade=MERGE
odercascade=ALL
annotation.Bidirektionale Beziehungen zwischen verwalteten Einheiten wird beibehalten, basierend auf Verweise im Besitz der besitzenden Seite
(Employee)
von der Beziehung. Es ist der Entwickler in der Verantwortung halten die in-memory-Verweise auf der zugehörigen Seite(Employee)
und denjenigen, die auf der inversen Seite(Department)
im Einklang mit einander, wenn Sie sich ändern. Also, mit unter eine Reihe von Anweisungen, die Beziehung wird synchronisiert die Datenbank mit einem einzigenmerge
:Diese änderungen werden an die Datenbank in die Transaktion ein commit. Die in-memory-Zustand der Entitäten synchronisiert werden können, um die Datenbank zu anderen Zeiten als gut, wenn eine Transaktion aktiv ist, indem Sie mit der EntityManager#flush Methode.
Department
und die änderungen werden kaskadiert, um die damit verbundenenemployees
.Department
, und dieemployees
Eigenschaft markiert ist, als cascading verschmilzt, dann dieEmployee
s werden zusammengeführt. Und wenn dieEmployee
s Staaten korrekt sind, dann werden die richtigen Daten in die Datenbank geschrieben.Haben Sie da eine bestehen - Betrieb (aus mit
em.merge()
). Das verharren eines neuen Mitarbeiters übernimmt nicht bedeuten, dass die Abteilung auch beibehalten (Sie haben keine Kaskadierung), so wird eine Ausnahme geworfen, weil ein anderer Grund (einfach probieren Sie es aus und poste die Ausnahme).Um zu vermeiden, dass Sie entweder fügen Sie eine cascading-Typ, oder verharren Sie beide (wie in deinem Beispiel).Zu deiner Frage: das einzige Teil, als wäre der besitzenden Seite.
In der JPA 2.0 Spezifikation,
Chapter 3 Entity Operations
=>3.2.4 Syncrhonization to the Database
ist der folgende:Im Zusammenhang mit der Notwendigkeit einer Transaktion: ja, Sie benötigen für den merge-Vorgang einer aktiven Transaktion. Auszug aus der JPA-2-Spezifikation:
Auf, wie eine Transaktion gestartet wird/wie Sie starat einer Transaktion: es kommt auf die Art der
EntityManager
(auf die Art und Weise, wie Sie eines bekommen). In EJB-es ist viel einfacher zu handhaben, die für Allgemeine Situationen. Auch, laut der Dokumentation der merge-Methode, eine TransactionRequiredException geworfen wird,if invoked on a container-managed entity manager of type PersistenceContextType.TRANSACTION and there is no transaction
.