休眠:在update()上覆盖合并() [英] Hibernate : Downside of merge() over update()

查看:101
本文介绍了休眠:在update()上覆盖合并()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了由Hibernate抛出的 NonUniqueObjectException 问题。

阅读文档和 这篇博客文章中,我将 update() merge(),并解决了这个问题。

我相信我理解异常的原因,以及为什么要改变方法来解决问题,以断开连接的对象和会话边界为准。



我的问题是:假定 merge()总是会解析为会话对象,或者如果它不存在,则检索它,调用merge()通常是比<$ c更安全的替代方法$ c> update()?



使用 merge() over update()

解决方案


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


blockquote>

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


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


一位未经评估的用户可能会认为他或她拥有一个新的托管实体。就像

  // myEntity(作为参数传递不会被管理)
//只有合并操作是一个托管实体
session.merge(myEntity);

//newValue未提交,因为myEntity未被管理
myEntity.setMyProperty(newValue);

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


  • 添加版本(@Version)列。 0或NULL版本表示实例是新的,必须插入,而不是更新

  • 使用Hibernate拦截器

  • 如果您确定要更新而不是插入,则可以使用以下方法:


...

  public void updateMyEntity(MyEntity updateableMyEntity); 

//加载不会触及数据库
MyEntity myEntity =(MyEntity)session.load(MyEntity.class,updateableMyEntity.getId());

BeanUtils.copyProperties(myEntity,updateableMyEntity);




$ b $ p
$ b

这样你就可以在不合并或更新方法的情况下更新实体。查看此问题以获取更多信息:最佳如何更新Hibernate上的分离对象的某些字段?


I'm having problems with a NonUniqueObjectException thrown by Hibernate.

Reading the docs, and this blog post, I replaced the call from update() to merge(), and it solved the problem.

I believe I understand the reason for the exception, and why changing the method fixed the problem, in terms of disconnected objects and session boundaries.

My question is : given that merge() will always resolve to the session object, or retrieve it if it doesn't exist, is calling merge() generally a safer alternative than update()?

What is the downside of using merge() over update()?

解决方案

Is calling merge() generally a safer alternative than update() ?

As a way to avoid NonUniqueObjectException, yes. I think it explains why JPA does not allow an update method.

What is the downside of using merge() over update() ?

An unadvised user may think he or she has a fresh managed entity. Something like

// 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");

And if your persistence context does not contain your entity, maybe you do not want select-before-updating default behavior. But it can be avoided

  • Add a version (@Version) column. 0 or NULL version indicates that an instance is new and has to be inserted, not updated
  • Use a Hibernate interceptor
  • If you are sure you want to update instead of inserting, you can use the following approach

...

public void updateMyEntity(MyEntity updateableMyEntity);

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

    BeanUtils.copyProperties(myEntity, updateableMyEntity);

}

This way you can update your entity without merge or update method. See this question for more information: Best way to update some fields of a detached object on Hibernate ?

这篇关于休眠:在update()上覆盖合并()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆