Я провел некоторое пробное тестирование, чтобы записать разницу между save()
и persist()
.
Похоже, что оба этих метода ведут себя одинаково при работе с Transient Entity, но различаются при работе с Detached Entity.
Для приведенного ниже примера возьмите EmployeeVehicle в качестве сущности с PK в качестве vehicleId
, который является сгенерированным значением, и vehicleName
в качестве одного из его свойств.
Пример 1: Работа с временным объектом
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = new EmployeeVehicle();
entity.setVehicleName("Honda");
session.save(entity);
// session.persist(entity);
session.getTransaction().commit();
session.close();
Результат:
select nextval ('hibernate_sequence') // This is for vehicle Id generated : 36
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Honda, 36)
Обратите внимание, что результат получается тот же, когда вы получаете уже сохраненный объект и сохраняете его
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
entity.setVehicleName("Toyota");
session.save(entity); -------> **instead of session.update(entity);**
// session.persist(entity);
Повторите то же самое с помощью persist(entity)
и получитерезультат тот же с новым идентификатором (скажем, 37, honda);
Пример 2. Работа с отдельным объектом
// Session 1
// Get the previously saved Vehicle Entity
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
session.close();
// Session 2
// Here in Session 2 , vehicle entity obtained in previous session is a detached object and now we will try to save / persist it
// (i) Using Save() to persist a detached object
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.save(entity);
session2.getTransaction().commit();
session2.close();
Результат: Возможно, вы ожидаете Автомобиль с идентификатором 36, полученным в предыдущемсессия обновлена с именем как "Тойота".Но происходит следующее: в БД сохраняется новая сущность с новым сгенерированным идентификатором и именем «Тойота»
select nextval ('hibernate_sequence')
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Toyota, 39)
Использование persist для сохранения отсоединенной сущности
// (ii) Using Persist() to persist a detached
// Session 1
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
session.close();
// Session 2
// Here in Session 2 , vehicle entity obtained in previous session is a detached object and now we will try to save / persist it
// (i) Using Save() to persist a detached
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.persist(entity);
session2.getTransaction().commit();
session2.close();
Результат:
Exception being thrown : detached entity passed to persist
Таким образом, всегда лучше использовать Persist (), а не Save (), так как при работе с переходным объектом необходимо осторожно использовать save.
Важное примечание: в приведенном вышеНапример, pk объекта транспортного средства является сгенерированным значением, поэтому при использовании save () для сохранения отсоединенного объекта Hibernate генерирует новый идентификатор для сохранения.Однако если этот pk не является сгенерированным значением, это приведет к нарушению ключа, указывающего на исключение.