Нюансы работы метода 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 все сделает сам. Если вы меняете объект, который “присоединен к базе”, то все его изменения будут записаны в базу.

Нюансы работы метода 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);   //тут кинется исключение

Метод saveOrUpdate()

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

В отличии от метода update(), он может менять передаваемый ему объект. Например, установить ему ID, который был присвоен при сохранении в базу данных. Пример:


User user = new User();
user.setName("Колян");
session.saveOrUpdate(user);   //объект будет записан в базу

Как это работает:

  • если у передаваемого объекта установлен ID, то вызывается SQL-метод UPDATE
  • если у передаваемого объекта ID не установлен, то вызывается SQL-метод INSERT
undefined
1
Задача
Модуль 4. Работа с БД, 11 уровень, 2 лекция
Недоступна
task1102
Сохрани объект animalCat в БД с помощью метода save объекта session, потом вызови метод saveOrUpdate для объектов animalCat и animalDog...