什么是Hibernate中的persist()和save()之间的区别?

M S*_*ach 13 hibernate

通过文档我可以发现只有一个区别是save方法生成返回对象作为生成的标识符但是persist没有.这是提供持久化方法的唯一目的.如果它是如何帮助程序员因为即使他不打算要使用生成的标识符,他可以使用save并忽略返回值.

还通过这个帖子来了解 Hibernate中persist()vs save()的优点是什么?.我可以从这个线程获得的有意义的语句是persist()还保证如果在事务边界之外调用它不会执行INSERT语句,保存方法但不确定我应该如何在我的程序中尝试它以便我可以得到实际的差异?

小智 15

我做了一些模拟测试来记录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();
Run Code Online (Sandbox Code Playgroud)

结果: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 ) ;
Run Code Online (Sandbox Code Playgroud)

示例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();
Run Code Online (Sandbox Code Playgroud)

结果:您可能希望在上一个会话中获得的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();
Run Code Online (Sandbox Code Playgroud)

// Session 2 //在Session 2中,在前一个会话中获得的车辆实体是一个分离的对象,现在我们将尝试保存/保存它(i)使用persist()来保存一个分离的对象

            Session session2 = factory.openSession();
    session2.beginTransaction();
            entity.setVehicleName("Toyota");
    session2.persist(entity);
    session2.getTransaction().commit();
    session2.close();
Run Code Online (Sandbox Code Playgroud)

结果:抛出异常:传递给持久化的分离实体

因此,最好使用Persist()而不是Save(),因为在处理会话和转换时必须小心使用save.


Pre*_*raj 5

  • 返回类型:两个函数都将记录插入数据库,但返回类型为persist()方法为void,而返回类型为save()的方法是由hibernate生成的主键id值.

  • 标识符:persist()方法不保证标识符值将立即分配给持久化实例,分配可能在刷新时发生.

  • 事务边界:我们只能在事务内部调用persist()方法,因此它是安全的并且可以处理任何级联对象.save()方法可以在事务内部或外部调用.

  • 上下文:persist()方法将实体对象添加到持久上下文并跟踪任何进一步的更改.在提交事务时保存任何进一步的更改,如persist.

最后persist()方法比save()更好.

例子