Нюансы работы метода 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
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ