JPA EntityManager: Warum persist() statt merge() verwenden?
EntityManager.merge()` kann neue Objekte einfügen und bestehende aktualisieren.
Warum sollte man "persist()" verwenden (das nur neue Objekte erstellen kann)?
920
3
In beiden Fällen wird eine Entität zu einem PersistenceContext hinzugefügt, der Unterschied liegt darin, was man anschließend mit der Entität macht.
Persist nimmt eine Entitätsinstanz, fügt sie dem Kontext hinzu und macht diese Instanz verwaltet (d.h. zukünftige Aktualisierungen der Entität werden verfolgt).
Merge erstellt eine neue Instanz Ihrer Entität, kopiert den Zustand der übergebenen Entität und macht die neue Kopie verwaltet. Die Instanz, die Sie übergeben, wird nicht verwaltet (alle Änderungen, die Sie vornehmen, werden nicht Teil der Transaktion - es sei denn, Sie rufen merge erneut auf).
Vielleicht hilft ein Codebeispiel weiter.
Szenario 1 und 3 sind ungefähr gleichwertig, aber es gibt einige Situationen, in denen man Szenario 2 verwenden sollte.
Mir ist aufgefallen, dass ich bei der Verwendung von "em.merge" für jede "INSERT"-Anweisung eine "SELECT"-Anweisung erhielt, selbst wenn es kein Feld gab, das JPA für mich generierte - das Primärschlüsselfeld war eine UUID, die ich selbst festgelegt hatte. Ich wechselte zu
em.persist(myEntityObject)
und bekam dann nur nochINSERT
-Anweisungen.Ich war immer lazyLoading Ausnahmen auf meine Entität, weil ich versuchte, eine Lazy geladen Sammlung zugreifen, die in Sitzung war.
Was ich tun würde, war in einer separaten Anforderung, die Entität aus der Sitzung abrufen und dann versuchen, eine Sammlung in meiner JSP-Seite zugreifen, die problematisch war.
Um das Problem zu lösen, habe ich dieselbe Entität in meinem Controller aktualisiert und an meine JSP-Seite übergeben, obwohl ich mir vorstelle, dass sie, wenn ich sie erneut in der Sitzung speichere, auch über
SessionScope
zugänglich ist und keineLazyLoadingException
auslöst, eine Änderung von Beispiel 2:Das Folgende hat bei mir funktioniert: