Hibernate:更新()下的merge()的缺点

Mar*_*itt 29 java session hibernate

我遇到了NonUniqueObjectExceptionHibernate抛出的问题.

阅读文档和这篇博客文章,我将调用替换update()merge(),并解决了问题.

我相信我理解异常的原因,以及为什么更改方法在断开连接的对象和会话边界方面解决了问题.

我的问题是:鉴于它merge()总会解析为会话对象,或者如果它不存在则检索它,调用merge()通常是一个比更安全的替代方案update()吗?

使用merge()结束有update()什么缺点?

Art*_*ald 41

调用merge()通常比update()更安全吗?

作为一种避免NonUniqueObjectException的方法,是的.我认为它解释了为什么JPA不允许更新方法.

使用merge()而不是update()的缺点是什么?

未经修改的用户可能认为他或她拥有新的管理实体.就像是

// myEntity (passed as parameter does not become managed)
// Only the one returned by the merge operation is a managed entity
session.merge(myEntity);

// "newValue" is not commited because myEntity is not managed
myEntity.setMyProperty("newValue");
Run Code Online (Sandbox Code Playgroud)

如果您的持久化上下文不包含您的实体,那么可能不希望选择更新前的默认行为.但它可以避免

  • 添加版本(@Version)列.0或NULL版本表示实例是新的,必须插入,而不是更新
  • 使用Hibernate拦截器
  • 如果您确定要更新而不是插入,则可以使用以下方法

...

public void updateMyEntity(MyEntity updateableMyEntity);

    // load does not hit the database
    MyEntity myEntity = (MyEntity) session.load(MyEntity.class, updateableMyEntity.getId());

    BeanUtils.copyProperties(myEntity, updateableMyEntity);

}
Run Code Online (Sandbox Code Playgroud)

这样,您可以在不使用合并或更新方法的情况下更新实体.有关更多信息,请参阅此问题:在Hibernate上更新分离对象的某些字段的最佳方法?

  • @Julia在Hibernate中,如果你有一个带有一些标识符的持久化实例(让我们称之为bubba),你的持久化上下文**已经包含一个具有相同标识符的托管实体**(让我们称之为forrest),如果你调用session.update (bubba)你会得到NonUniqueObjectException,因为Hibernate*不能假设哪个对象代表当前状态*Hibernate应该更新bubba或forrest的状态吗?你能看到吗你能明白吗 ?所以**因为一致性问题**,我想JPA(标准持久性)允许**只****合并方法(不会抛出NonUniqueException)而不是更新 (5认同)