Jaka jest różnica między persist () i merge () w JPA i Hibernate?

119

Jaka jest różnica między persist () i merge () w Hibernate?

persist() może utworzyć zapytanie UPDATE & INSERT, np .:

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

w tym przypadku zapytanie zostanie wygenerowane w następujący sposób:

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

więc persist()metoda może wygenerować wstawkę i aktualizację.

Teraz z merge():

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

Oto co widzę w bazie danych:

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

Teraz zaktualizuj rekord za pomocą 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();

Oto co widzę w bazie danych:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley
Jimit Tank
źródło
7
Dokument javadoc zawiera bardzo szczegółowe informacje na temat tego, co robią i jakie są różnice. Przeczytałeś i zrozumiałeś to?
skaffman

Odpowiedzi:

144

Specyfikacja JPA zawiera bardzo precyzyjny opis semantyki tych operacji, lepszy niż w javadoc:

Semantyka trwałej operacji zastosowanej do jednostki X jest następująca:

  • Jeśli X jest nową jednostką, staje się zarządzana. Jednostka X zostanie wprowadzona do bazy danych podczas lub przed zatwierdzeniem transakcji lub w wyniku operacji opróżniania.

  • Jeśli X jest istniejącą wcześniej jednostką zarządzaną, jest ignorowana przez operację utrwalania. Jednak utrzymują się operacja jest kaskadowo podmiotom odwołuje X, jeśli relacje od X do tych innych podmiotów są opisywane z cascade=PERSISTlub cascade=ALL wartość elementu adnotacji lub określony z równoważnego elementu deskryptora XML.

  • Jeśli X jest usuniętą jednostką, staje się zarządzana.

  • Jeśli X jest odłączonym obiektem, EntityExistsExceptionmoże zostać zgłoszony, gdy wywoływana jest operacja utrwalania, lub ten EntityExistsExceptionlub inny PersistenceExceptionmoże zostać zgłoszony w czasie opróżniania lub zatwierdzania.

  • Dla wszystkich obiektów Y, do których odwołuje się relacja z X, jeśli relacja do Y została opatrzona adnotacją wartością elementu kaskadowego cascade=PERSISTlub cascade=ALLoperacja utrwalania jest stosowana do Y.


Semantyka operacji scalania zastosowana do jednostki X jest następująca:

  • Jeśli X jest jednostką odłączoną, stan X jest kopiowany do istniejącej instancji jednostki zarządzanej X 'o tej samej tożsamości lub tworzona jest nowa zarządzana kopia X' X.

  • Jeśli X jest nową instancją jednostki zarządzanej, tworzona jest nowa instancja jednostki zarządzanej X ', a stan X jest kopiowany do nowej instancji jednostki zarządzanej X'.

  • Jeśli X jest usuniętą instancją jednostki, IllegalArgumentExceptionoperacja scalania spowoduje zgłoszenie an (lub zatwierdzenie transakcji nie powiedzie się).

  • Jeśli X jest jednostką zarządzaną, jest ignorowana przez operację scalania, jednak operacja scalania jest kaskadowana do jednostek, do których odwołują się relacje z X, jeśli te relacje zostały opatrzone adnotacją z wartością elementu kaskadowego cascade=MERGElub cascade=ALLadnotacją.

  • Dla wszystkich jednostek Y, do których odwołują się relacje z X, które mają wartość elementu kaskadowego cascade=MERGElub cascade=ALL, Y jest scalane rekurencyjnie jako Y '. Dla wszystkich takich Y, do których odnosi się X, X 'jest ustawiane jako odniesienie Y'. (Zauważ, że jeśli X jest zarządzany, X jest tym samym obiektem co X ').

  • Jeśli X jest jednostką scaloną z X ', z odniesieniem do innej jednostki Y, gdzie cascade=MERGElub cascade=ALLnie jest określona, ​​wówczas nawigacja po tym samym powiązaniu z X' daje odniesienie do zarządzanego obiektu Y 'o tej samej trwałej tożsamości co Y.

axtavt
źródło
Dzięki za informację. Widzę semantykę obu definicji. Ale pytanie dotyczy różnic między nimi. Być może przedstaw listę stanów i 2 podsekcje dla każdego innego zachowania persistvs merge?
AlikElzin-kilaka
25

To pochodzi z JPA. W bardzo prosty sposób:

  • persist(entity) powinien być używany z zupełnie nowymi encjami, aby dodać je do DB (jeśli jednostka już istnieje w DB, zostanie rzucony EntityExistsException).

  • merge(entity) powinien być używany, aby umieścić jednostkę z powrotem w kontekście trwałości, jeśli jednostka została odłączona i została zmieniona.

Krystian
źródło
czy możesz dodać źródło do swojego wyjaśnienia? Dzięki.
AlikElzin-kilaka
@ AlikElzin-kilaka takie wyjaśnienie, o ile pamiętam, znalazłem w książce „Beginning Java EE 7”.
Krystian
12

Persist powinno być wywoływane tylko w przypadku nowych jednostek, podczas gdy scalanie ma na celu ponowne dołączenie odłączonych jednostek.

Jeśli używasz przypisanego generatora, użycie funkcji scalania zamiast trwałego może spowodować powstanie nadmiarowej instrukcji SQL , co wpłynie na wydajność.

Ponadto, nazywając seryjnej dla podmiotów zarządzanych jest również błędem, ponieważ podmioty zarządzane są automatycznie zarządzane przez Hibernate i ich stan jest zsynchronizowany z rekordu bazy danych przez mechanizm kontroli brudny po spłukiwania Context Persistence .

Vlad Mihalcea
źródło
1

Najważniejsza różnica jest taka:

  • W przypadku persistmetody, jeśli jednostka, która ma być zarządzana w kontekście trwałości, już istnieje w kontekście trwałości, nowa jest ignorowana. (Nic się nie stało)

  • Jednak w przypadku mergemetody jednostka, która jest już zarządzana w kontekście trwałości, zostanie zastąpiona nową jednostką (zaktualizowana), a kopia tej zaktualizowanej jednostki zostanie zwrócona. (od teraz wszelkie zmiany powinny być dokonywane w tej zwracanej encji, jeśli chcesz odzwierciedlić zmiany w kontekście trwałości)

Od Chan
źródło