В чем разница между persist () и merge () в Hibernate?
persist()
может создать запрос UPDATE & INSERT, например:
SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();
в этом случае запрос будет сгенерирован так:
Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?
так что persist()
метод может генерировать вставку и обновление.
Теперь с merge()
:
SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();
Вот что я вижу в базе данных:
SINGER_ID SINGER_NAME
1 Ricky Martin
2 Madonna
3 Elvis Presley
4 Luciano Pavarotti
Теперь обновите запись, используя 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();
Вот что я вижу в базе данных:
SINGER_ID SINGER_NAME
1 Ricky Martin
2 Luciano Pavarotti
3 Elvis Presley
Ответы:
Спецификация JPA содержит очень точное описание семантики этих операций, лучше, чем в javadoc:
источник
persist
vsmerge
?Это исходит от
JPA
. Очень просто:persist(entity)
следует использовать с совершенно новыми объектами, чтобы добавить их в БД (если объект уже существует в БД, будет выброшено исключение EntityExistsException).merge(entity)
следует использовать, чтобы вернуть объект в контекст персистентности, если объект был отсоединен и изменен.источник
Persist следует вызывать только для новых сущностей, в то время как слияние предназначено для повторного присоединения отдельных сущностей.
Если вы используете назначенный генератор, использование слияния вместо сохранения может вызвать избыточный оператор SQL , что повлияет на производительность.
Кроме того, вызов слияния для управляемых сущностей также является ошибкой, поскольку управляемые сущности автоматически управляются Hibernate, и их состояние синхронизируется с записью базы данных с помощью механизма грязной проверки при сбросе контекста постоянства .
источник
Самое важное отличие заключается в следующем:
В случае
persist
метода, если объект, которым нужно управлять в контексте постоянства, уже существует в контексте постоянства, новый игнорируется. (Ничего не произошло)Но в случае
merge
метода сущность, которая уже управляется в контексте персистентности, будет заменена новой сущностью (обновленной), и копия этой обновленной сущности вернется обратно. (с этого момента любые изменения должны быть внесены в этот возвращенный объект, если вы хотите отразить свои изменения в контексте сохранения)источник