3

我正在开发一个 spring-hibernate-envers 应用程序。经过大量谷歌搜索后,事情终于对我有用,但我仍然有几个问题。

  1. 早些时候我saveOrUpdate用于保存或更新实体。但是在使用 envers 时,它抛出了一个nonUniqueObject 异常。所以我merge改用它并且它起作用了。为此使用合并是否正确?是否merge将新对象插入数据库?

  2. 我尝试了以下代码:

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

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

4

2 回答 2

10

休眠参考说:

saveOrUpdate() 执行以下操作:

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

和 merge() 非常不同:

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

这意味着saveOrUpdate()如果您确定具有相同标识符的对象未与会话关联,则可以使用。否则你应该使用merge().

以下代码

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

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

于 2011-03-15T12:59:15.767 回答
0

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

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

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

于 2011-03-15T13:00:35.770 回答