1071 Stimmen

JPA EntityManager: Warum persist() statt merge() verwenden?

EntityManager.merge() kann neue Objekte einfügen und bestehende aktualisieren.

Warum sollte man die persist() (die nur neue Objekte erstellen kann)?

14 Stimmen

2 Stimmen

Wenn Sie Diagramme mögen. Siehe dies: spitballer.blogspot.in/2010/04/

18voto

Khurshed Salimov Punkte 231

Einige weitere Details über Merge, die Ihnen helfen werden, Merge über Persist zu verwenden:

Die Rückgabe einer verwalteten Instanz, die nicht die ursprüngliche Entität ist, ist ein wichtiger Teil der Zusammenführung Prozesses. Wenn eine Entitätsinstanz mit demselben Bezeichner bereits im Persistenzkontext vorhanden ist, überschreibt der Provider seinen Zustand mit dem Zustand der Entität, die zusammengeführt wird, überschreiben, aber die verwaltete Version, die bereits existierte, muss an den Client zurückgegeben werden, damit sie verwendet werden kann. Wenn der Anbieter nicht die Instanz Employee im Persistenzkontext nicht aktualisiert hat, werden alle Verweise auf diese Instanz inkonsistent mit dem neuen Zustand, der zusammengeführt wird.

Wenn merge() für eine neue Entität aufgerufen wird, verhält es sich ähnlich wie die Operation persist(). Sie fügt die Entität zum Persistenzkontext hinzu, aber anstatt die ursprüngliche Entitätsinstanz hinzuzufügen, wird eine neue Kopie und verwaltet diese Instanz stattdessen. Die Kopie, die durch die merge()-Operation erzeugt wird, wird persistiert persistiert, als ob die persist()-Methode für sie aufgerufen worden wäre.

Bei Vorhandensein von Beziehungen wird die Operation merge() versuchen, die verwaltete Entität zu aktualisieren so zu aktualisieren, dass sie auf verwaltete Versionen der Entitäten verweist, die von der abgetrennten Entität referenziert werden. Wenn die Entität eine Beziehung zu einem Objekt hat, das keine dauerhafte Identität hat, ist das Ergebnis der Merge-Operation undefiniert. Einige Anbieter erlauben es, dass die verwaltete Kopie auf das nicht-persistente Objekt verweist, während andere sofort eine Ausnahme auslösen können. Die merge()-Operation kann optional kaskadiert werden, um das Auftreten einer Ausnahme zu verhindern. Wir werden die Kaskadierung der merge() Operation wird später in diesem Abschnitt behandelt. Wenn eine zusammenzuführende Entität auf eine entfernte Entität verweist, wird eine IllegalArgumentException Ausnahme geworfen.

Lazy-Loading-Beziehungen sind ein Sonderfall des Zusammenführungsvorgangs. Wenn eine lazy-loading Beziehung für eine Entität nicht ausgelöst wurde, bevor sie losgelöst wurde, wird diese Beziehung ignoriert, wenn die Entität zusammengeführt wird. Wenn die Beziehung ausgelöst wurde, während sie verwaltet wurde, und dann auf null gesetzt wurde, während die Entität abgetrennt wurde, wird die Beziehung in der verwalteten Version der Entität während der Zusammenführung ebenfalls gelöscht."

Alle oben genannten Informationen wurden aus "Pro JPA 2 Mastering the Java™ Persistence API" von Mike Keith und Merrick Schnicariol entnommen. Kapitel 6. Abschnittsabtrennung und -zusammenführung. Bei diesem Buch handelt es sich um das zweite Buch der Autoren, das sich mit JPA befasst. Dieses neue Buch hat viele neue Informationen als das vorherige. Ich empfehle dieses Buch wirklich für alle, die sich ernsthaft mit JPA beschäftigen. Es tut mir leid, dass ich meine erste Antwort anonymerweise gepostet habe.

18voto

V G Punkte 18518

Es gibt noch einige weitere Unterschiede zwischen merge y persist (Ich werde die hier bereits veröffentlichten Beispiele erneut aufzählen):

D1. merge macht die übergebene Entität nicht verwaltet, sondern gibt eine andere Instanz zurück, die verwaltet wird. persist auf der anderen Seite wird die übergebene Einheit verwaltet:

//MERGE: passedEntity remains unmanaged, but newEntity will be managed
Entity newEntity = em.merge(passedEntity);

//PERSIST: passedEntity will be managed after this
em.persist(passedEntity);

D2. Wenn Sie eine Entität entfernen und dann beschließen, die Entität wieder zu persistieren, dürfen Sie das nur mit persist() tun, weil merge wirft eine IllegalArgumentException .

D3. Wenn Sie sich dafür entschieden haben, Ihre IDs manuell zu verwalten (z. B. durch Verwendung von UUIDs), dann ist ein merge Vorgang löst nachfolgende SELECT Abfragen, um nach existierenden Entitäten mit dieser ID zu suchen, während persist benötigen diese Abfragen möglicherweise nicht.

D4. Es gibt Fälle, in denen Sie dem Code, der Ihren Code aufruft, einfach nicht trauen, und um sicherzustellen, dass keine Daten aktualisiert, sondern vielmehr eingefügt werden, müssen Sie persist .

11voto

Amit Gujarathi Punkte 1022

JPA ist unbestreitbar eine große Vereinfachung im Bereich der Unternehmens Anwendungen, die auf der Java-Plattform aufgebaut sind. Als ein Entwickler, der sich mit den der sich mit den Feinheiten der alten Entity Beans in J2EE herumschlagen musste, sehe ich die die Aufnahme von JPA in die Java EE-Spezifikationen als einen großen Sprung Fortschritt. Wenn ich jedoch tiefer in die JPA-Details eindringe, finde ich Dinge, die nicht so einfach sind. In diesem Artikel befasse ich mich mit dem Vergleich von merge- und persist-Methoden des EntityManagers, deren überschneidendes Verhalten nicht nur für Neulinge verwirrend sein kann. Außerdem schlage ich eine Verallgemeinerung vor, die beide Methoden als Spezialfälle einer allgemeineren Methode combine sieht.

Fortbestehende Entitäten

Im Gegensatz zur Merge-Methode ist die Persist-Methode ziemlich einfach und intuitiv. Das häufigste Szenario für die Verwendung der Persist-Methode lässt sich wie folgt zusammenfassen:

"Eine neu erstellte Instanz der Entitätsklasse wird an die persist-Methode übergeben. Nachdem diese Methode zurückkehrt, wird die Entität verwaltet und für die Einfügung in die Datenbank geplant. Dies kann beim oder vor dem Commit der Transaktion geschehen oder wenn die Flush-Methode aufgerufen wird. Wenn die Entität eine andere Entität durch eine Beziehung referenziert, die mit der PERSIST-Kaskadenstrategie gekennzeichnet ist, wird dieses Verfahren auch auf sie angewendet."

enter image description here

Die Spezifikation geht mehr ins Detail, aber es ist nicht wichtig, sich diese zu merken, da diese Details nur mehr oder weniger exotische Situationen abdecken.

Verschmelzung von Einheiten

Im Vergleich zu persist ist die Beschreibung des Verhaltens der Verschmelzung nicht so einfach. Es gibt kein Hauptszenario, wie im Fall von persist, und ein Programmierer muss sich alle Szenarien merken, um einen korrekten Code zu schreiben. Es scheint mir, dass die JPA-Designer eine Methode haben wollten, deren Hauptaufgabe es ist, losgelöste Entitäten zu behandeln (im Gegensatz zur persist-Methode, die sich in erster Linie mit neu erstellten Entitäten befasst). Die Hauptaufgabe der merge-Methode besteht darin, den Zustand einer nicht verwalteten Entität (die als Argument übergeben wird) auf ihr verwaltetes Gegenstück innerhalb des Persistenzkontexts zu übertragen. Diese Aufgabe teilt sich jedoch in mehrere Szenarien auf, die die Verständlichkeit des Gesamtverhaltens der Methode verschlechtern.

Anstatt Absätze aus der JPA-Spezifikation zu wiederholen, habe ich ein Flussdiagramm erstellt, das das Verhalten der Merge-Methode schematisch darstellt:

enter image description here

Wann sollte ich also persistieren und wann fusionieren?

beharren

  • Sie möchten, dass die Methode immer eine neue Entität erstellt und niemals eine Entität aktualisiert. Andernfalls löst die Methode eine Ausnahme als Folge der Verletzung der Eindeutigkeit des Primärschlüssels aus.
  • Batch-Prozesse, die Entitäten auf zustandsbehaftete Weise behandeln (siehe Gateway-Muster).
  • Optimierung der Leistung

zusammenführen

  • Sie möchten, dass die Methode entweder eine Entität in die Datenbank einfügt oder aktualisiert.
  • Sie wollen Entitäten zustandslos behandeln (Datenübertragungsobjekte in Diensten)
  • Sie möchten eine neue Entität einfügen, die einen Verweis auf eine andere Entität haben kann, die möglicherweise noch nicht erstellt wurde (die Beziehung muss als MERGE gekennzeichnet sein). Beispiel: Sie möchten ein neues Foto mit einem Verweis auf ein neues oder ein bereits vorhandenes Album einfügen.

0 Stimmen

Was ist der Unterschied zwischen Ist E verwaltet und Enthält der PC eine verwaltete Version von E?

8voto

logixplayer Punkte 920

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 dies zu lindern, aktualisierte ich die gleiche Entität in meinem Controller und übergab sie an meine JSP, obwohl ich mir vorstelle, wenn ich wieder in der Sitzung gespeichert, dass es auch zugänglich sein wird, obwohl SessionScope und nicht eine LazyLoadingException eine Abwandlung von Beispiel 2:

Bei mir hat sich folgendes bewährt:

// scenario 2 MY WAY
// tran starts
e = new MyEntity();
e = em.merge(e); // re-assign to the same entity "e"

//access e from jsp and it will work dandy!!

8voto

Ray Hulha Punkte 9831

Ich fand diese Erklärung aus den Hibernate-Dokumenten aufschlussreich, weil sie einen Anwendungsfall enthalten:

Die Verwendung und Semantik von merge() scheint für neue Benutzer verwirrend zu sein. Erstens: Solange Sie nicht versuchen, den in einem Entity Manager geladenen Objektstatus in einem anderen neuen Entity Manager zu verwenden, sollten Sie Sie brauchen merge() überhaupt nicht zu verwenden. . Einige vollständige Anwendungen werden diese Methode nie verwenden.

Normalerweise wird merge() im folgenden Szenario verwendet:

  • Die Anwendung lädt ein Objekt in den ersten Entity Manager
  • das Objekt wird an die Präsentationsschicht weitergegeben
  • einige Änderungen an dem Objekt vorgenommen werden
  • das Objekt wird an die Geschäftslogikschicht zurückgegeben
  • die Anwendung behält diese Änderungen bei, indem sie merge() in einem zweiten Entity Manager aufruft

Hier ist die genaue Semantik von merge():

  • wenn es eine verwaltete Instanz mit demselben Bezeichner gibt, die derzeit mit dem Persistenzkontext verbunden ist, kopiere den Zustand des angegebenen Objekts auf die verwaltete Instanz
  • wenn dem Persistenzkontext derzeit keine verwaltete Instanz zugeordnet ist, versuchen Sie, sie aus der Datenbank zu laden, oder erstellen Sie eine neue verwaltete Instanz
  • die verwaltete Instanz wird zurückgegeben
  • die gegebene Instanz wird nicht mit dem Persistenzkontext assoziiert, sie bleibt losgelöst und wird normalerweise verworfen

Von: http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/objectstate.html

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X