1. Нюанси роботи методу merge()

Якщо ти хочеш за допомогою Hibernate змінити об'єкт, який вже збережено в базі, для цього також є кілька методів.

По-перше, це метод merge(), який оновлює інформацію в базі на основі переданого об'єкта. При цьому викличеться SQL-запит UPDATE. Приклад:


User user = new User();
user.setName("Колян");
session.save(user);
 
session.evict(user); // від'єднуємо об'єкт від сесії
user.setName("Маша");
 
User user2 = (User) session.merge(user);

Тут є кілька важливих нюансів.

По-перше, метод merge() повертає результат — оновлений об'єкт. Цей об'єкт має стан Persist та його приєднано до об'єкта session. Водночас об'єкт, що передається до методу merge(), не змінюється.

Може здатися, що між user та user2 немає різниці, але це не так. До методу merge() можна передати POJO об'єкт, а як результат метод може повернути proxy (залежить від налаштувань Hibernate). Тому просто запам'ятай, що метод merge() не змінює об'єкт, що передається.

По-друге, якщо об'єкт, що передається до merge(), має статус Transient (і у нього немає ID), то для нього створиться окремий рядок у базі даних. Іншими словами, буде виконана команда persist().

По-третє, якщо до методу merge() передати об'єкт, вже приєднаний до сесії (зі статусом Persist), то нічого не відбудеться: метод просто поверне цей же об'єкт. Чому? А все тому, що під час коміту транзакції дані все одно запишуться до бази:


User user = new User();
user.setName("Микола");
session.save(user);
 
user.setName("Марія"); //змінюємо об'єкт приєднаний до сесії
 
session.close(); //В базу запишуться всі змінені об'єкти

Не потрібно зберігати об'єкт після будь-яких його змін. Якщо цей об'єкт у статусі Persist, то Hibernate все зробить сам. Якщо ти змінюєш об'єкт, який “приєднано до бази”, всі його зміни будуть записані до бази.

2. Нюанси роботи методу update()

Також Hibernate має метод update(), який як і метод save() дістався йому від попередніх версій. За допомогою цього методу можна лише оновити дані збереженого об'єкта. При цьому буде викликано SQL-запит UPDATE. Приклад:


User user = new User();
user.setName("Микола");
session.save(user);
 
session.evict(user); // від'єднуємо об'єкт від сесії
user.setName("Марія");
 
session.update(user);

Цей метод нічого не повертає і не змінює наявний об'єкт.

Якщо викликати цей метод для нового об'єкта, то просто кинеться виняток:


User user = new User();
user.setName("Колян");
session.update(user); //тут кинеться виняток

3. Метод saveOrUpdate()

До появи JPA функцію методу persist() виконував метод saveOrUpdate(). Його завданням було оновити в базі інформацію щодо існуючого об'єкта, а якщо такого немає, створити його. Його майже завжди використовують замість методів save() та update().

На відміну від методу update(), він може змінювати об'єкт, що йому передається. Наприклад, встановити йому ID, який було присвоєно при збереженні до бази даних. Приклад:


User user = new User();
user.setName("Микола");
session.saveOrUpdate(user); //об'єкт буде записаний до бази

Як це працює:

  • якщо у об'єкта, що передається, встановлений ID, то викликається SQL-метод UPDATE
  • якщо у переданого об'єкта ID не встановлено, то викликається SQL-метод INSERT