Hibernate中的persist()和save()有什么区别?
通过文档,我只能找到一个区别,即save method generates将对象作为生成的标识符返回,但persist不返回。这是提供persist method的唯一目的吗?如果是,这对程序员有什么帮助?因为即使他不打算使用生成的标识符,他也可以使用save并忽略返回价值观 也通过这个线程在。我可以从这个线程得到的有意义的语句是persist(),它还保证,如果在save方法执行的事务边界之外调用INSERT语句,它将不会执行INSERT语句,但不确定我应该如何在程序中尝试它,以便获得实际的差异?save()返回标识符,如果必须执行插入以获取标识符,则无论您在事务内部还是外部,插入都会立即发生。在具有扩展会话/持久性上下文的长时间运行会话中,这是不好的Hibernate中的persist()和save()有什么区别?,hibernate,Hibernate,通过文档,我只能找到一个区别,即save method generates将对象作为生成的标识符返回,但persist不返回。这是提供persist method的唯一目的吗?如果是,这对程序员有什么帮助?因为即使他不打算使用生成的标识符,他也可以使用save并忽略返回价值观 也通过这个线程在。我可以从这个线程得到的有意义的语句是persist(),它还保证,如果在save方法执行的事务边界之外调用INSERT语句,它将不会执行INSERT语句,但不确定我应该如何在程序中尝试它,以便获得实际的差
persist()用于瞬态对象。它使临时实例持久化。但是,它不能保证标识符值将立即分配给持久实例,分配可能在刷新时发生。它还保证,如果在事务边界之外调用INSERT语句,则不会执行INSERT语句。这在具有扩展会话/持久性上下文的长时间运行对话中很有用。我做了一些模拟测试来记录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();
结果:选择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”
//第2次会议
//在会话2中,在上一个会话中获得的车辆实体是一个分离的对象,现在我们将尝试保存/持久化它
(i) 使用persist()保存分离的对象
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.persist(entity);
session2.getTransaction().commit();
session2.close();
结果:引发异常:已分离的实体传递给persist
因此,最好使用Persist()而不是Save(),因为在处理会话和事务时必须小心使用Save。Persist():
- 它是一个void方法,不保证标识符值为空 在插入后分配给持久性实例。这个任务可能会 在齐平时间发生
- 如果从外部事务调用它,则不会执行它 边界
- 它对于具有扩展会话/持久性上下文的长时间运行的对话非常有用
- 它将在执行INSERT后返回标识符
- 即使在事务边界之外也会执行
- 它对于长时间运行的对话没有用处
public class TestMain {
public static void main(String[] args) {
Person person = new Person();
saveEntity(person);
}
private static void saveEntity(Person person) {
person.setId(1);
person.setName("Concretepage1");
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(person);
session.getTransaction().commit();
session.close();
}
若我们试图在事务边界之外持久化数据,那个么会出现异常 - 返回类型:两个函数都将记录插入数据库,但persist()方法的返回类型为void,而save()方法的返回类型为hibernate生成的主键id值
- 标识符:persist()方法不能保证标识符值将立即分配给持久实例,分配可能在刷新时发生
- 事务边界:我们只能在事务内部调用persist()方法,因此它是安全的,并且可以处理任何级联对象。save()方法可以在事务内部或外部调用
- 上下文:persist()方法将实体对象添加到持久上下文中,并跟踪任何进一步的更改。任何进一步的更改都会在提交事务时保存,如persist
public class HibernateSaveExample {
public static void main(String[] args) {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Student student = new Student("javabycode.com", new Date(), "USA", "1234569");
Long studentId = (Long) session.save(student);
System.out.println(" Identifier : " + studentId);
System.out.println(" Successfully saved");
Session session2 = sessionFactory.openSession();
Transaction trans = session2.beginTransaction();
Student student2 = new Student("javabycode.com", new Date(), "USA", "1234569");
Long studentId2 = (Long) session2.save(student2);
trans.commit();
System.out.println(" Identifier : " + studentId2);
System.out.println(" Successfully saved");
sessionFactory.close();
}
}
而persist()方法无法做到这一点
Hibernate中的save和persist方法还有一个区别:JPA支持persist,而Hibernate只支持save
从教程来看,这并不完全正确。如果记录存在,
save
不会更新,您必须为此调用safe或update
<代码>保存在这种情况下会引发异常。您的答案在某些方面非常混乱和错误。当您提到persist()用于瞬态对象时,您的答案听起来好像save()不用于瞬态对象。另外,save()作为update()是错误的。如果实体是持久的,但没有分离,然后使用save或persistent,那么可能会发生重复?一个实体如何同时处于两种状态(持久和分离)?hibernate“长时间运行的对话”到底是什么?
public class TestMain {
public static void main(String[] args) {
Person person = new Person();
saveEntity(person);
}
private static void saveEntity(Person person) {
person.setId(1);
person.setName("Concretepage1");
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(person);
session.getTransaction().commit();
session.close();
}
public class HibernateSaveExample {
public static void main(String[] args) {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Student student = new Student("javabycode.com", new Date(), "USA", "1234569");
Long studentId = (Long) session.save(student);
System.out.println(" Identifier : " + studentId);
System.out.println(" Successfully saved");
Session session2 = sessionFactory.openSession();
Transaction trans = session2.beginTransaction();
Student student2 = new Student("javabycode.com", new Date(), "USA", "1234569");
Long studentId2 = (Long) session2.save(student2);
trans.commit();
System.out.println(" Identifier : " + studentId2);
System.out.println(" Successfully saved");
sessionFactory.close();
}
}