通过文档,我发现只有一个区别就是save方法生成的对象作为生成的标识符返回,但是persist却没有。这是提供持久化方法的唯一目的。如果是程序员如何帮助它,即使他不打算使用生成的标识符,他可以使用save并忽略返回值。
同样来自What's the advantage of persist() vs save() in Hibernate?的这个主题。我可以从这个线程获得的有意义的语句 persist()还保证如果在事务边界之外调用它不会执行INSERT语句,保存方法但不确定我应该如何尝试它在我的程序中,以便我可以获得实际的差异?
答案 0 :(得分:14)
我做了一些模拟测试来记录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')
//这是针对生成的车辆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,名称为“丰田”
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节 //在会话2中,在前一个会话中获得的车辆实体是一个分离的对象,现在我们将尝试保存/保留它 (i)使用persist()来保存分离的对象
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.persist(entity);
session2.getTransaction().commit();
session2.close();
结果:抛出异常:传递给persist的分离实体
因此,最好使用Persist()而不是Save(),因为在处理会话和转换时必须小心使用save。
答案 1 :(得分:5)
返回类型:两个函数都将记录INSERT到数据库中,但返回类型为persist()方法为void,而返回类型为save()的方法是主键id值为由hibernate生成。
标识符:persist()方法不保证标识符值会立即分配给持久化实例,分配可能会在刷新时发生。
事务边界:我们只能在事务内部调用persist()方法,因此它是安全的并且可以处理任何级联对象。 save()方法可以在事务内部或外部调用。
上下文:persist()方法将实体对象添加到持久上下文并跟踪任何进一步的更改。在提交事务时保存任何进一步的更改,如persist。
最后persist()方法优于save()。
答案 2 :(得分:3)
save()返回一个标识符,如果必须执行INSERT来获取标识符,则无论您是在事务内部还是外部,都会立即执行此INSERT。这与使用扩展的会话/持久性上下文的长时间对话不太好。
persist()用于瞬态对象。它使瞬态实例持久化。但是,它不保证标识符值将立即分配给持久性实例,分配可能在刷新时发生。它还保证如果在事务边界之外调用它,它将不会执行INSERT语句。这对于具有扩展会话/持久性上下文的长时间运行会话非常有用。
答案 3 :(得分:3)
<强>留存():强>
保存():强>
答案 4 :(得分:2)
public class TestSave {
public static void main(String[] args) {
Session session= HibernateUtil.getSessionFactory().openSession();
Person person= (Person) session.get(Person.class, 1);
System.out.println(person.getName());
session.close();
Session session1= HibernateUtil.getSessionFactory().openSession();
session1.beginTransaction();
person.setName("person saved with Persist");
session1.getTransaction().commit();
System.out.println(session1.save(person));
//session1.persist(person);
session1.flush();
session1.close();
}
}
保存和保持之间的区别,保存在事务外部执行。执行上面的代码并检查控制台System.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();
}
如果我们尝试将数据保留在事务边界之外,则会给出异常。
答案 5 :(得分:0)
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。