据我所知,如果没有其他具有相同id和类型的对象附加到会话,则更新用于将分离的对象置于持久状态。合并并不关心国家。它只返回一个相同类型的持久化对象,如果它不存在于会话中,或者它使用新对象的值更新旧对象。我的问题是关于数据库命中。该方法是否更新'和'合并'立即打到数据库?或会话结束时数据库中的更改。
编辑:如果我们通过save方法在持久化实例上调用update方法会发生什么?我认为更新方法只用于分离的实例。
答案 0 :(得分:4)
Hibernate会在刷新会话时处理对会话中对象的任何更改。如果对象的实例已在会话中,则更新可能会失败。在这种情况下应该使用合并。它将分离对象的更改与会话中的对象(如果存在)合并。
更新:如果您确定会话不包含具有相同标识符的已持久实例,则使用update将数据保存在休眠中
合并:如果你想在不知道会话状态的情况下随时保存你的修改,那么在hibernate中使用merge()。
当实体实例处于持久状态时,您对该实例的映射字段所做的所有更改将在刷新Session时应用于相应的数据库记录和字段。持久化实例可以被认为是“在线”,而分离的实例已经“脱机”并且不会监视更改。
这意味着当您更改持久对象的字段时,您不必调用save,update或任何这些方法来对数据库进行这些更改:您只需要提交事务,或者刷新或者当你完成它时关闭会话。 重要的是要了解所有方法(持久,保存,更新,合并,saveOrUpdate)不会立即导致相应的SQL UPDATE或INSERT语句。 在提交事务或刷新会话时实际将数据保存到数据库。
答案 1 :(得分:0)
合并时: 当我们在分离的实例上调用merge方法时,它将使用更新后的值对其进行更新。
如果有更新 当我们在分离的实例上调用update方法时,它将给出异常 org.hibernate.NonUniqueObjectException
答案 2 :(得分:0)
休眠中的所有方法
保存
合并
saveOrUpdate
更新
删除
不会立即导致sql更新或插入语句。
实际的数据保存发生在我们提交或刷新会话时。
答案 3 :(得分:0)
有时候,我们会遇到这样的情况:我们的应用程序数据库已被某些外部应用程序/代理修改,因此您的应用程序中相应的休眠实体实际上与数据库表示不同步,即具有旧数据。在这种情况下,可以使用session.refresh()
方法用数据库中可用的最新数据重新填充实体。
您可以在Session接口上使用refresh()
方法之一来刷新持久对象的实例
方法merge()
与refresh()
的作用恰好相反,即,它使用来自分离实体的值更新数据库。刷新方法是使用最新的数据库信息更新实体。所以基本上,两者是完全相反的。
当您希望将分离实体再次更改为持久状态,并且将分离实体的更改迁移到(或覆盖)数据库时,将执行合并。
休眠官方文档对merge()
方法给出了很好的解释:
将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有与该会话关联的持久实例,则将其加载。返回持久实例。如果给定的实例未保存,请保存的副本并将其作为新的持久实例返回。给定的实例不与会话关联。如果关联是用cascade=”merge”
映射的,则此操作将级联到关联的实例。