wake-up-neo.com

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

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

persist() kann eine UPDATE & INSERT-Abfrage erstellen, zB:

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

in diesem Fall wird query folgendermaßen generiert:

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

also kann persist() method generate ein Insert und ein Update.

Jetzt mit merge():

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

Das 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();

Das sehe ich in der Datenbank:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley
115
Jimit Tank

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

Die Semantik der persistierenden 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 bei oder vor dem Festschreiben der Transaktion oder als Ergebnis der Löschoperation in die Datenbank eingegeben.

  • Wenn X eine bereits vorhandene verwaltete Entität ist, wird sie von der Operation persist ignoriert. Die Persist-Operation wird jedoch auf Entitäten kaskadiert, auf die von X verwiesen wird, wenn die Beziehungen von X zu diesen anderen Entitäten mit dem Annotationselementwert cascade=PERSIST Oder cascade=ALL Oder mit dem entsprechenden XML-Deskriptorelement angegeben werden .

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

  • Wenn X ein nicht verbundenes Objekt ist, wird beim Aufrufen der dauerhaften Operation möglicherweise das EntityExistsException ausgelöst, oder das EntityExistsException oder ein anderes PersistenceException wird möglicherweise zum Zeitpunkt des Flushs oder Commits ausgelöst.

  • Wenn für alle Entitäten Y, auf die durch eine Beziehung von X verwiesen wird, die Beziehung zu Y mit dem Kaskadenelementwert cascade=PERSIST Oder cascade=ALL Kommentiert wurde, wird die Daueroperation 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 'mit derselben Identität kopiert, oder es wird 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, wird beim Zusammenführen ein IllegalArgumentException ausgelöst (oder das Festschreiben der Transaktion schlägt fehl).

  • Wenn X eine verwaltete Entität ist, wird sie von der Zusammenführungsoperation ignoriert. Die Zusammenführungsoperation wird jedoch auf Entitäten kaskadiert, auf die durch Beziehungen von X verwiesen wird, wenn diese Beziehungen mit dem Kaskadenelementwert cascade=MERGE Oder cascade=ALL Anmerkung.

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

  • Wenn X eine Entität ist, die mit X 'zusammengeführt wurde, mit einem Verweis auf eine andere Entität Y, wobei cascade=MERGE Oder cascade=ALL Nicht angegeben ist, ergibt die Navigation derselben Assoziation von X' einen Verweis auf a verwaltetes Objekt Y 'mit derselben persistenten Identität wie Y.

142
axtavt

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 eine EntityExistsException ausgelöst).

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

22
Krystian

Persist sollte nur für neue Entitäten aufgerufen werden, während Merge dazu gedacht ist, getrennte Entitäten wieder zuzuordnen.

Wenn Sie den zugewiesenen Generator verwenden, kann die Verwendung von merge anstelle von persist kann zu einer redundanten SQL-Anweisung führen und damit die Leistung beeinträchtigen.

Außerdem ist Aufrufen der Zusammenführung für verwaltete Entitäten ebenfalls ein Fehler, da verwaltete Entitäten automatisch von Hibernate verwaltet werden und ihr Status mit dem Datenbankdatensatz durch den Dirty-Checking-Mechanismus bei - synchronisiert wird. Löscht den Persistenzkontext .

11
Vlad Mihalcea

der wichtigste Unterschied ist folgender: Bei der Persist-Methode wird die neue ignoriert, wenn die Entität, die im Persistenzkontext verwaltet werden soll, bereits im Persistenzkontext vorhanden ist. (NICHTS ist passiert) Im Falle einer Zusammenführungsmethode wird die Entität, die bereits im Persistenzkontext verwaltet wird, durch die neue Entität ersetzt (aktualisiert) und eine Kopie dieser aktualisierten Entität wird zurückgegeben. (Ab sofort sollten alle Änderungen an dieser zurückgegebenen Entität vorgenommen werden, wenn Sie Ihre Änderungen im Persistenzkontext widerspiegeln möchten.)

1
Od Chan