我做了一些模拟测试来记录 Save() 和 Persist() 之间的区别。
听起来这两种方法在处理瞬态实体时表现相同,但在处理分离实体时表现不同。
对于下面的示例,将 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') //这是为生成的车辆 ID:36
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Honda, 36)
Repeat the same with using persist(entity) and will result the same with new Id ( say 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();
结果:您可能期望在上一个会话中获得的具有 id : 36 的车辆已更新为名称为 "Toyota" 。但是发生的情况是,一个新实体被保存在数据库中,为生成的新 ID 和名称为“Toyota”
select nextval ('hibernate_sequence')
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Toyota, 39)
(ii) Using Persist() to persist a detached object
// Session 1
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
session.close();
// 会话 2
// 这里在 Session 2 中,在前一个 session 中获得的车辆实体是一个分离的对象,现在我们将尝试保存/持久化它
(i) 使用 persist() 来持久化一个分离的对象
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.persist(entity);
session2.getTransaction().commit();
session2.close();
结果:抛出异常:分离的实体传递给持久化
因此,使用 Persist() 而不是 Save() 总是更好,因为在处理会话和事务时必须小心使用 save。