Яка різниця між персистентом () та злиттям () у JPA та сплячому режимі?


119

Яка різниця між персистентом () та злиттям () у сплячому режимі?

persist() можна створити ОНОВЛЕННЯ І ВСТАВИТИ запит, наприклад:

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()метод може генерувати Insert and Update.

Зараз із 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

7
Явадок дуже чітко стосується того, чим вони займаються, і чим відрізняються. Ви читали і розуміли це?
скафман


Відповіді:


144

Специфікація JPA містить дуже точний опис семантики цих операцій, краще, ніж у javadoc:

Семантика операції, що зберігається , застосовується до сутності X така:

  • Якщо X є новою сутністю, вона стає керованою. Суб'єкт X буде введено в базу даних під час або до здійснення транзакції або в результаті операції флеш.

  • Якщо X є суттєвим керованим об'єктом, воно ігнорується операцією, що зберігається. Однак операція, що зберігається, каскадується до сутностей, на які посилається X, якщо зв'язки від X до цих інших об'єктів анотуються зі значенням елемента cascade=PERSISTабо cascade=ALLанотації або задаються з еквівалентним елементом дескриптора XML.

  • Якщо X - видалена сутність, вона стає керованою.

  • Якщо X є відокремленим об'єктом, він EntityExistsExceptionможе бути кинутий, коли викликається тривала операція, EntityExistsExceptionабо інша PersistenceExceptionможе бути кинута під час потоку або введення часу.

  • Для всіх сутностей Y, на які посилається відношення від X, якщо відношення до Y було позначено значенням каскадного елемента cascade=PERSISTабо cascade=ALL, збережена операція застосовується до Y.


Семантика операції злиття, застосована до сутності X, така:

  • Якщо X є відокремленою сутністю, стан X копіюється на попередньо існуючий екземпляр керованої сутності X 'тієї самої ідентичності або створюється нова керована копія X' з X.

  • Якщо X є новим екземпляром сутності, створюється новий керований екземпляр сутності X ', а стан X копіюється в новий керований екземпляр об'єкта X'.

  • Якщо X - це видалений екземпляр об'єкта, IllegalArgumentExceptionоперація злиття буде викинута (або фіксація транзакції вийде з ладу).

  • Якщо X є керованою сутністю, вона ігнорується операцією злиття, однак операція злиття каскадується до об'єктів, на які посилаються відносини з X, якщо ці зв'язки були позначені значенням каскадного елемента cascade=MERGEабо cascade=ALLанотацією.

  • Для всіх сутностей Y, на які посилаються відносини від X, що мають значення каскадного елемента, cascade=MERGEабо cascade=ALLY об'єднується рекурсивно як Y '. Для всіх таких Y, на які посилається X, X 'встановлюється як посилання Y'. (Зверніть увагу, що якщо X управляється, то X є тим же об'єктом, що і X '.

  • Якщо X є об'єднанням, об'єднаним у X ', із посиланням на інший об'єкт Y, де cascade=MERGEабо cascade=ALLне вказано, то навігація тієї ж асоціації з X' дає посилання на керований об'єкт Y 'з такою ж стійкою ідентичністю, що і Y.


Дякуємо за інформацію. Я бачу семантику обох визначень. Але питання полягає в відмінностях між ними. Можливо, представити список станів та 2 підрозділи для кожної різної поведінки persistvs merge?
АлікЕльзін-кілака

25

Це походить JPA. Дуже простим способом:

  • persist(entity) слід використовувати з абсолютно новими об'єктами, щоб додати їх до БД (якщо сутність вже існує в БД, буде EntityExistsException).

  • merge(entity) слід використовувати, щоб повернути сутність в контекст стійкості, якщо сутність була відменена і була змінена.


чи можете ви додайте джерело до свого пояснення? Дякую.
AlikElzin-kilaka

@ AlikElzin-kilaka таке пояснення, як я пам’ятаю, я знайшов у книзі «Початок Java EE 7».
Крістіян

12

Персист слід називати лише для нових об'єктів, тоді як об'єднання має на увазі повторне приєднання відокремлених об'єктів.

Якщо ви використовуєте призначений генератор, використання об'єднання замість збереження може спричинити надмірний оператор SQL , що впливає на продуктивність.

Крім того, виклик злиття для керованих об'єктів також є помилкою, оскільки керованими об'єктами автоматично керує Hibernate, а їх стан синхронізується із записом бази даних брудним механізмом перевірки при змиві з контексту постійності .


1

Найголовніша відмінність полягає в цьому:

  • У разі persistметоду, якщо сутність, якою слід керувати в контексті стійкості, вже існує в контексті стійкості, нова ігнорується. (Нічого не сталося)

  • Але у випадку mergeметоду сутність, якою вже керується в контексті стійкості, буде замінена новою сутністю (оновлена), а копія цього оновленого об'єкта повернеться назад. (відтепер будь-які зміни повинні бути внесені в цьому поверненому об'єкті, якщо ви хочете відобразити ваші зміни в контексті постійності)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.