Hibernate 会话中保存、更新、保存或更新、合并方法之间的差异?
我对Hibernate还不熟悉,上周已经完成了Hibernate教程。我对会话类中的save、update、saveOrUpdate和merge方法有一些疑问。这些是:Hibernate 会话中保存、更新、保存或更新、合并方法之间的差异?,hibernate,Hibernate,我对Hibernate还不熟悉,上周已经完成了Hibernate教程。我对会话类中的save、update、saveOrUpdate和merge方法有一些疑问。这些是: 保存方法:用于在数据存储中插入新创建的对象。(对于此项,基本上标识符值为0)。就像我创建一个新客户并调用save操作一样,它将把它保存在数据存储中并生成标识符 这是正确的吗?如果我们在已经持久化的对象上调用save,不确定会发生什么 更新方法:用于更新数据存储中已经存在的持久对象。(基本上,标识符值将是一些非零值)。就像我加载
- 保存方法:用于在数据存储中插入新创建的对象。(对于此项,基本上标识符值为0)。就像我创建一个新客户并调用save操作一样,它将把它保存在数据存储中并生成标识符 这是正确的吗?如果我们在已经持久化的对象上调用save,不确定会发生什么
- 更新方法:用于更新数据存储中已经存在的持久对象。(基本上,标识符值将是一些非零值)。就像我加载一个新客户并在更新某个字段值后调用更新操作一样,它将在数据存储中更新它 根据我的理解,它应该会失败,但有一些例外,因为根据API更新是针对分离对象的。这是正确的吗?如果是,我们应该调用什么来更新同一会话中的对象(我的意思是如果对象未分离)。另一点是:如果我们在新创建的对象上调用update,将会发生什么
- saveOrUpdate方法:它将根据未保存的值检查调用上述任一方法(必须根据标识符零值或非零值进行检查,对吗?),因此,如果我们有持久的客户对象,并且我们更新了他的姓氏并创建了一个新帐户,那么saveOrUpdate将处理它 我理解对了吗
- 合并方法:它的作用类似于更新,但在这里,如果会话中已存在具有相同标识符的持久对象,它将更新持久对象中分离的对象值并保存它 但是,如果当前没有与会话关联的持久实例,这将从数据存储中加载持久对象,然后在加载的持久对象中更新分离对象的值,然后更新它 我也收到了吗
- 您的所有评估都完全正确。你明白了
对于第一个问题,如果我没记错的话,
save
专门做了一个插入。因此,再次调用save将导致数据库中出现另一行
对于第二个问题,
update
更新会话中的对象。因此,如果对象在会话中,它将更新。如果对象不在会话中,则应调用merge。我相信为分离的实例调用update
会导致异常。大多数事情都是正确的,但update的工作原理与您描述它的方式略有不同。如果对象在会话中(即持久),则完全不需要更新。Hibernate处理刷新会话时对会话中对象的任何更改的持久化。对它们调用update不会起任何作用(并且可能会导致性能损失;我不确定)
Update设计用于在分离的对象上调用,即那些现在位于加载它们的会话之外的对象@hvgotcodes解释似乎不正确,因为只有当对象不在会话中时才应该调用update。如果对象的实例已在会话中,则更新可能失败。在这种情况下,应该使用Merge。它将分离对象的更改与会话中的对象(如果存在)合并。如果会话中没有对象,它将创建一个新对象
通常情况下,您可以完全避免调用update/merge,但如果最终不得不调用一个,merge将处理更广泛的情况。我的理解是,使用更新的唯一原因是为了更好的性能,假设您知道它不会出错
对其他一些hibernate方法也有很好的总结
编辑:我只是想说合并和更新之间的区别比我原来说的要多。Update将给定的实体修改为持久性,而merge将返回一个新的持久性实体。对于合并,您应该扔掉旧对象。另一个区别是merge在决定是否写入其数据之前,通过从DB中选择来执行脏检查,而update总是将其数据持久化到DB中,不管它是否脏 可能还有其他一些小差别。通过记录生成的SQL来测试Hibernate行为总是很好的,因为行为并不总是与文档匹配,至少在我的经验中是这样。session.update()-它用于从Hibernate会话加载对象Person1的场景。现在它正在应用程序中使用-可能也在客户端,已经更新。我们想再次拯救它。我们知道数据库中的Person对象并没有做任何更改。所以我们可以简单地使用update session.merge()-在上述场景中,如果在保存更改的Person1对象之前对person数据进行了更改,那么我们应该使用merge。它将合并更改 session.save()-可用于保存新对象。它返回可序列化的标识 session.persist()-它与save()相同,但是void方法,不返回任何内容 session.saveOrUpdate()-此方法适用于新对象和旧对象。若对象是新的,它将像简单保存一样工作;若对象已经是持久的,它将像更新一样工作 session.lock()-它仅用于锁定对象,也可以说是检查对象的版本。它不是用来更新对象的。只有当您确定数据库中的对象状态尚未更改时,才应使用它重新附加对象。否则,它可能会覆盖更改关于这一点,请提供更多信息。
update()
用于分离的对象和瞬态对象。如果在持久对象上调用,它将抛出一个ununiqueobjectexception
,这将通过merge()
SessionFactory factory = cfg.buildSessionFactory();
Session session1 = factory.openSession();
Student student1 = null;
Object object1 = session1.get(Student.class, new Integer(101));
student1 = (Student)object1;
session1.close();
student1.setMarks(97);// -->object will be in some RAM location, not in the session1 cache
Session session2 = factory.openSession();
Student student2 = null;
Object object2 = session2.get(Student.class, new Integer(101));
student2 = (Student)object2;
Transaction tx=session2.beginTransaction();
session2.merge(student1);