开发者

Dynamic-update with JPA

开发者 https://www.devze.com 2023-01-25 03:52 出处:网络
I was surprised to recently learn that the default hibernate behavior is to update all of the fields in an object if only a single change is made and merge is called.

I was surprised to recently learn that the default hibernate behavior is to update all of the fields in an object if only a single change is made and merge is called.

Dynamic-update is the field that allows you to configure an alternative approach of just updating the changed field...

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

I am using JPA with hibernate and I tried to add the following

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

to my class (previously it only had the JPA annotation)

Anyway, i've been monitoring the sql and unfortunately it didn't change it and I'm still seeing every field updated.

This is my java that updates the object...

    @Transactional(rea开发者_运维百科dOnly = false, propagation = Propagation.REQUIRES_NEW)    
public void setAccountStatusForUser(String username, AccountStatus act){
    User u = this.getUser(username);
    u.setAccountStatus(act);
    this.update(u);
}

and the update method does the following:

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

Any help would greatly be appreciated.


Some questions to help you :

  • How does your getUser() method work ?
  • Don't you use detached objects ?
  • Is the associated record actually fully loaded from the database ?

Detached objects are not linked with any original version, thus the origin of the word detached. This helps hibernate from doing any comparison, which forces it to do a full upgrade.

As I saw on Springsource Forum, it works only when the option select-before-update is set to true which seems quite logical as Hibernate has to now what actually changed. The select-before-update option forces it to have read the original.

If your application reads the User completely from the database and is not working with detached objects then I can't help you with more ideas...


From the hibernate documentation:

Be sure to import @javax.persistence.Entity to mark a class as an entity. It's a common mistake to import @org.hibernate.annotations.Entity by accident.


You're reattaching a detached object via the call to merger(). In that case you must turn on selectBeforeUpdate. This is in the javadocs.

0

精彩评论

暂无评论...
验证码 换一张
取 消