Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate中的persist()和save()有什么区别?_Hibernate - Fatal编程技术网

Hibernate中的persist()和save()有什么区别?

Hibernate中的persist()和save()有什么区别?,hibernate,Hibernate,通过文档,我只能找到一个区别,即save method generates将对象作为生成的标识符返回,但persist不返回。这是提供persist method的唯一目的吗?如果是,这对程序员有什么帮助?因为即使他不打算使用生成的标识符,他也可以使用save并忽略返回价值观 也通过这个线程在。我可以从这个线程得到的有意义的语句是persist(),它还保证,如果在save方法执行的事务边界之外调用INSERT语句,它将不会执行INSERT语句,但不确定我应该如何在程序中尝试它,以便获得实际的差

通过文档,我只能找到一个区别,即save method generates将对象作为生成的标识符返回,但persist不返回。这是提供persist method的唯一目的吗?如果是,这对程序员有什么帮助?因为即使他不打算使用生成的标识符,他也可以使用save并忽略返回价值观

也通过这个线程在。我可以从这个线程得到的有意义的语句是persist(),它还保证,如果在save方法执行的事务边界之外调用INSERT语句,它将不会执行INSERT语句,但不确定我应该如何在程序中尝试它,以便获得实际的差异?

save()返回标识符,如果必须执行插入以获取标识符,则无论您在事务内部还是外部,插入都会立即发生。在具有扩展会话/持久性上下文的长时间运行会话中,这是不好的


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后返回标识符
  • 即使在事务边界之外也会执行
  • 它对于长时间运行的对话没有用处
保存和持久化之间的区别,保存在事务外部执行。执行上述代码并检查控制台系统。out.println(session1.save(person))将返回标识符并再次执行,它将增加您的标识符。现在,如果您尝试使用下面的代码在数据库中的Person表中保存另一条记录,并刷新数据库表并检查数据库中的id列。它的值将增加

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

最后,persist()方法优于save()

save()方法通常在事务外部插入语句

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();
    }

}