hibernate envers:merge& saveOrUpdate

时间:2011-03-15 12:48:13

标签: java hibernate hibernate-envers

我正在开发一个spring-hibernate-envers应用程序。很多谷歌搜索后的东西终于为我工作了,但我仍然有几个问题。

  1. 早些时候我正在使用saveOrUpdate 保存或更新实体。但 当与envers一起工作时 投掷nonUniqueObject 例外。所以我使用了merge代替 它起作用了。是否正确使用 合并为此? merge是否会插入 db的新对象?

  2. 我尝试了以下代码:

  3. entity=merge(entity);  
    saveOrUpdate(entity);
    

    这也有效。这是正确的方法吗?而且我很好奇为什么saveOrUpdate现在没有抛出任何错误。

2 个答案:

答案 0 :(得分:10)

Hibernate Reference说:

  

saveOrUpdate()执行以下操作:

     
      
  • 如果该对象在此会话中已经持久,则不执行任何操作
  •   
  • 如果与会话关联的其他对象具有相同的标识符,则抛出异常
  •   
  • 如果对象没有标识符属性,则保存()它
  •   
  • 如果对象的标识符具有分配给新实例化对象的值,则保存()它
  •   
  • 如果对象由or版本化,并且version属性值是分配给新实例化对象的相同值,则save()it
  •   
  • 否则更新()对象
  •   
     

和merge()非常不同:

     
      
  • 如果存在具有当前与会话关联的相同标识符的持久性实例,则将给定对象的状态复制到持久性实例
  •   
  • 如果当前没有与会话关联的持久性实例,请尝试从数据库加载它,或者创建新的持久性实例
  •   
  • 返回持久化实例
  •   
  • 给定的实例没有与会话关联,它仍然是分离的
  •   

如果您确定具有相同标识符的对象与会话无关,则表示您可以使用saveOrUpdate()。否则,您应该使用merge()

以下代码

entity=merge(entity);
saveOrUpdate(entity); 

有效,因为merge()的结果是一个持久对象,因此它被saveOrUpdate()忽略,所以第二行没有任何意义。

答案 1 :(得分:0)

saveOrUpdate:如果请求的对象是瞬态的(空主键值),则将其保留在数据库中或更新它。条件是会话中只有该实体的一个副本。

合并: Hibernate将首先检查持久性实例中是否已存在该类型的持久性实例 上下文。它使用对象标识符来检查这种存在。如果存在另一个实例,则复制状态 将Detached对象放入现有的Persistence对象中。如果不存在其他实例, Hibernate只是重新附加Detached对象。

如果会话包含单个实体的多个副本,则使用最新实体更新所有副本。 在您调用update之前,它不会在数据库中更新。