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

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

persist() można 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 używając 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 baza danych:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley
Author: Vlad Mihalcea, 2010-12-22

3 answers

Specyfikacja JPA zawiera bardzo dokładny opis semantyki tych operacji, lepszy niż w javadoc:

Semantyka persist operacji, stosowane do encji X są jak następuje:

  • Jeśli X jest nowym podmiotem, to staje się zarządzany. Encja X będzie wprowadzone do bazy danych w dniu lub przed transakcji lub w wyniku operacja spłukiwania.

  • Jeśli X jest a preexisting zarządzany podmiot, jest ignorowane przez operację persist. Jednak operacja persist jest kaskadowe do encji, do których odwołuje się X, jeśli relacje od X do tych inne podmioty są przypisane do cascade=PERSIST LUB cascade=ALL wartość elementu adnotacji lub określona z równoważnym deskryptorem XML element.

  • Jeśli X jest usuniętym podmiotem, staje się zarządzany.

  • Jeśli X jest a wolnostojący obiekt, EntityExistsException może być wyrzucony when the persist operacja jest wywoływana, lub EntityExistsException lub innym PersistenceException może być rzucony w kolorze lub popełnić czas.

  • Na wszystkie podmioty y, do których odnosi się a relacja z X, jeśli związek z Y został przypisany z wartością elementu kaskadowego cascade=PERSIST LUB cascade=ALL, operacja persist jest stosowana do Y.


Semantyka operacji merge stosowane do encji X są następujące:

  • If X jest podmiotem wyodrębnionym, Państwo X jest kopiowany na wcześniej istniejący managed entity instance X' tego samego tożsamość lub nowa kopia zarządzana X' Z X jest stworzony.

  • Jeżeli X jest nowym podmiotem instancja, nowy podmiot zarządzany instancja X ' jest tworzona i stan X jest kopiowany do nowego zarządzanego instancja encji X".

  • Jeśli X jest a usunięta instancja encji, an IllegalArgumentException będzie rzucony przez operację scalania (lub zatwierdzanie transakcji fail).

  • If X jest zarządzanym podmiotem, jest ignorowany przez operacja scalania, jednak operacja scalania jest kaskadowa do / align = "left" / od X jeśli te relacje mają dodane przez kaskada wartość elementu cascade=MERGE lub cascade=ALL adnotacja.

  • Dla wszystkich / align = "left" / od X posiadające element kaskadowy wartość cascade=MERGE lub cascade=ALL, Y jest scalana rekurencyjnie jako Y'. Dla wszystkich takie y przez X, X ' jest ustawione na reference Y". (Zauważ, że jeśli X jest managed then X jest tym samym obiektem co X".)

  • Jeżeli X jest podmiotem scalonym do X", z odniesieniem do innego podmiotu Y, gdzie cascade=MERGE lub cascade=ALL jest nie określono, następnie nawigacja to samo skojarzenie z X ' daje a odniesienie do zarządzanego obiektu Y ' Z ta sama trwała tożsamość co Y.

 137
Author: axtavt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-22 12:57:06

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

Persist (entity) powinien być używany z całkowicie nowymi encjami, aby dodać je do DB (jeśli encja już istnieje w DB, to Entity Existsexception throw).

Należy użyć Merge(entity), aby przywrócić entity do kontekstu persistence, jeśli encja została odłączona i zmieniona.

 16
Author: Krystian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-04 12:40:39

Persist powinien być wywoływany tylko dla nowych encji, podczas gdy merge ma na celu ponowne podłączenie odłączonych encji.

Jeśli używasz przypisanego generatora, używanie merge zamiast persist może spowodować redundantne polecenie SQL, wpływając tym samym na wydajność.

Również, wywołanie merge dla zarządzanych jednostek jest również błędem, ponieważ zarządzane jednostki są automatycznie zarządzane przez Hibernate, a ich stan jest synchronizowany z rekordem bazy danych przez dirty checking mechanizm na flushing the Persistence Context .

 8
Author: Vlad Mihalcea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-04 12:26:57