Was ist der Unterschied zwischen persist () und merge () in JPA und Hibernate?

119

Was ist der Unterschied zwischen persist () und merge () im Ruhezustand?

persist() kann eine UPDATE & INSERT-Abfrage erstellen, z.

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();

In diesem Fall wird die Abfrage wie folgt generiert:

Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?

So persist()kann die Methode ein Einfügen und ein Aktualisieren generieren .

Jetzt mit merge():

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

Folgendes sehe ich in der Datenbank:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Madonna
3           Elvis Presley
4           Luciano Pavarotti

Aktualisieren Sie nun einen Datensatz mit merge()

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setId(2);
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

Folgendes sehe ich in der Datenbank:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley
Jimit Tank
quelle
7
Der Javadoc ist sehr explizit darüber, was sie tun und was die Unterschiede sind. Hast du es gelesen und verstanden?
Skaffman
1
Überprüfen Sie stackoverflow.com/questions/161224/…
Jigar Joshi

Antworten:

144

Die JPA-Spezifikation enthält eine sehr genaue Beschreibung der Semantik dieser Operationen, besser als in Javadoc:

Die Semantik der Persist- Operation, die auf eine Entität X angewendet wird, lautet wie folgt:

  • Wenn X eine neue Entität ist, wird sie verwaltet. Die Entität X wird beim oder vor dem Festschreiben der Transaktion oder als Ergebnis der Spüloperation in die Datenbank eingegeben.

  • Wenn X eine bereits vorhandene verwaltete Entität ist, wird sie von der Persist-Operation ignoriert. Allerdings gibt es weiterhin die Operation an Einheiten durch X referenzierten kaskadiert wird, wenn die Beziehungen von X auf diese anderen Einheiten mit dem annotierten sind cascade=PERSISToder cascade=ALL Annotation Elementwert oder mit dem äquivalenten XML - Descriptor - Elemente angegeben.

  • Wenn X eine entfernte Entität ist, wird sie verwaltet.

  • Wenn X ein getrenntes Objekt ist, EntityExistsExceptionkann das Objekt ausgelöst werden, wenn die Persist-Operation aufgerufen wird, oder das EntityExistsExceptionoder ein anderes Objekt PersistenceExceptionkann zur Flush- oder Commit-Zeit ausgelöst werden.

  • Wenn für alle Entitäten Y, auf die durch eine Beziehung von X verwiesen wird, die Beziehung zu Y mit dem Kaskadenelementwert cascade=PERSISToder kommentiert wurde cascade=ALL, wird die Persist-Operation auf Y angewendet.


Die Semantik der Zusammenführungsoperation , die auf eine Entität X angewendet wird, lautet wie folgt:

  • Wenn X eine getrennte Entität ist, wird der Status von X auf eine bereits vorhandene verwaltete Entitätsinstanz X 'derselben Identität kopiert oder eine neue verwaltete Kopie X' von X erstellt.

  • Wenn X eine neue Entitätsinstanz ist, wird eine neue verwaltete Entitätsinstanz X 'erstellt und der Status von X in die neue verwaltete Entitätsinstanz X' kopiert.

  • Wenn X eine entfernte Entitätsinstanz ist, IllegalArgumentExceptionwird eine durch die Zusammenführungsoperation ausgelöst (oder das Transaktions-Commit schlägt fehl).

  • Wenn X eine verwaltete Entität ist, wird sie von der Zusammenführungsoperation ignoriert. Die Zusammenführungsoperation wird jedoch an Entitäten kaskadiert, auf die durch Beziehungen von X verwiesen wird, wenn diese Beziehungen mit dem Wert cascade=MERGEoder der cascade=ALLAnnotation des Kaskadenelements versehen wurden .

  • Für alle Entitäten Y, auf die durch Beziehungen von X mit dem Kaskadenelementwert cascade=MERGEoder verwiesen wird cascade=ALL, wird Y rekursiv als Y 'zusammengeführt. Für alle Y, auf die X verweist, wird X 'auf Y' gesetzt. (Beachten Sie, dass X das gleiche Objekt wie X 'ist, wenn X verwaltet wird.)

  • Wenn X eine mit X 'zusammengeführte Entität ist, mit einem Verweis auf eine andere Entität Y, wo cascade=MERGEoder cascade=ALLnicht angegeben, ergibt die Navigation derselben Zuordnung von X' einen Verweis auf ein verwaltetes Objekt Y 'mit derselben persistenten Identität wie Y.

axtavt
quelle
Danke für die Information. Ich sehe die Semantik beider Definitionen. Aber die Frage ist nach den Unterschieden zwischen ihnen. Präsentieren Sie vielleicht die Liste der Zustände und 2 Unterabschnitte für jedes unterschiedliche Verhalten von persistvs merge?
AlikElzin-Kilaka
25

Das kommt von JPA. Auf sehr einfache Weise:

  • persist(entity) sollte mit völlig neuen Entitäten verwendet werden, um sie zur Datenbank hinzuzufügen (wenn die Entität bereits in der Datenbank vorhanden ist, wird EntityExistsException ausgelöst).

  • merge(entity) sollte verwendet werden, um die Entität wieder in den Persistenzkontext zu versetzen, wenn die Entität getrennt und geändert wurde.

Krystian
quelle
Können Sie Ihrer Erklärung bitte eine Quelle hinzufügen? Vielen Dank.
AlikElzin-Kilaka
@ AlikElzin-kilaka Eine solche Erklärung habe ich, wie ich mich erinnere, in einem Buch "Beginning Java EE 7" gefunden.
Krystian
12

Persist sollte nur für neue Entitäten aufgerufen werden, während Merge dazu dient, getrennte Entitäten wieder zu verbinden.

Wenn Sie den zugewiesenen Generator verwenden, kann die Verwendung von Merge anstelle von Persist eine redundante SQL-Anweisung verursachen und somit die Leistung beeinträchtigen.

Das Aufrufen der Zusammenführung für verwaltete Entitäten ist ebenfalls ein Fehler, da verwaltete Entitäten automatisch von Hibernate verwaltet werden und ihr Status beim Löschen des Persistenzkontexts durch den Dirty-Checking-Mechanismus mit dem Datenbankdatensatz synchronisiert wird .

Vlad Mihalcea
quelle
1

Der wichtigste Unterschied ist folgender:

  • persistWenn bei einer Methode die Entität, die im Persistenzkontext verwaltet werden soll, bereits im Persistenzkontext vorhanden ist, wird die neue ignoriert. (Nichts ist passiert)

  • Im Falle einer mergeMethode wird die Entität, die bereits im Persistenzkontext verwaltet wird, durch die neue Entität (aktualisiert) ersetzt, und eine Kopie dieser aktualisierten Entität wird zurückgegeben. (Von nun an sollten Änderungen an dieser zurückgegebenen Entität vorgenommen werden, wenn Sie Ihre Änderungen im Persistenzkontext widerspiegeln möchten.)

Od Chan
quelle