使用JPA进行动态更新

时间:2010-11-16 17:13:38

标签: performance hibernate jpa

我很惊讶最近才知道默认的hibernate行为是更新对象中的所有字段,如果只进行了一次更改并调用了merge。

动态更新是允许您配置仅更新已更改字段的替代方法的字段...

http://www.mkyong.com/hibernate/hibernate-dynamic-update-attribute-example/

我正在使用JPA和hibernate,我试图添加以下

@javax.persistence.Entity
@org.hibernate.annotations.Entity(dynamicInsert=true, dynamicUpdate=true) 

到我的班级(以前只有JPA注释)

无论如何,我一直在监控sql,不幸的是它没有改变它,我仍然看到每个字段都在更新。

这是我更新对象的java ...

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)    
public void setAccountStatusForUser(String username, AccountStatus act){
    User u = this.getUser(username);
    u.setAccountStatus(act);
    this.update(u);
}

并且update方法执行以下操作:

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
  public Object update(Object o) {
      Object a = this.entityManager.merge(o);
      this.entityManager.flush();
      return a;
}

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

有些问题可以帮助您:

  • 您的getUser()方法如何运作?
  • 你不使用分离的物体吗?
  • 相关记录是否实际上已从数据库中完全加载?

已分离的对象未与任何原始版本链接,因此分离的一词的来源。这有助于休眠进行任何比较,从而迫使它进行全面升级。

正如我在Springsource Forum上看到的那样,只有当select-before-update选项设置为true时它才有效,这似乎很合乎逻辑,因为Hibernate现在必须实际改变。 select-before-update选项强制它读取原文。

如果您的应用程序完全从数据库中读取User并且不使用分离的对象,那么我无法帮助您提供更多想法...

答案 1 :(得分:0)

来自hibernate文档:

  

确保导入@ javax.persistence.Entity将类标记为实体。偶然导入@ org.hibernate.annotations.Entity是一个常见的错误。

答案 2 :(得分:0)

您通过调用merger()重新附加一个分离的对象。在这种情况下,您必须打开selectBeforeUpdate。这是在javadocs中。