Java – get the previous value of the object field hibernate JPA

Let's assume I have this course:

@EntityListeners({MyListener.class})
class MyClass {
  String name;
  String surname;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name; 
  }

  public String getSurname() {
    return name;
  }

  public void setSurname(String name) {
    this.name = name; 
  }

  public void save() {
    JPA.em().persist(this);
    return this;
  }

  public void update() {
    JPA.em().merge(this);
  }

  public static MyClass findById(Long id) {
    return JPA.em().find(MyClass.class,id);
  }
}

Now in the mylistener class, I try to find out the previous MyClass instance value and the new value to be saved (Updated) to the database I do this with preupdate metdhod:

@PreUpdate
public void preUpdate(Object entity) {
...some logic here...unable to get the old object value in here           
}

So suppose I have a MyClass object instance with first and last names:

MyClass mycls = new MyClass();
mycls.setName("Bob");
mycls.setSurname("Dylan");
mycls.save();

This doesn't sound good because I'm listening for updates Now, if I update this instance as follows:

MyClass cls = MyClass.findById(someLongId)
cls.setSurname("Marley");
cls.update();

So this will trigger the preupdate method in mylistener when I try:

MyClass.findById(someLongId);

When I debug, I have got the newly updated instance, but the update hasn't happened yet, because when I check the database, the column name is still Dylan

How do I get the value of the database from my preupdate method instead of the value I just updated?

Solution

I think a simple way is to save the previous value in a temporary variable, JPA will not persist

If you want to save multiple attributes, it will be easy if your class MyClass is serializable

If so, add a post load listener

public class MyClass implements Serializable {

     @Transient
     private transient MyClass savedState;

     @PostLoad
     private void saveState(){
        this.savedState = SerializationUtils.clone(this); // from apache commons-lang
     }

}

Note, however, that savedstate is a separate instance

You can then access the previous state in the entitylistener

You can also move the postload listener to the entitylistener class However, you need to access the savedstate field I suggest using it as a scope restriction or using an accessor that encapsulates a scope, and putting MyClass and mylistener in the same package,

public class MyListener {

    @PostLoad
    private void saveState(MyClass myClass){
         myClass.saveState(SerializationUtils.clone(myClass)); // from apache commons-lang
    }

}

public class MyClass implements Serializable {

     @Transient
     private transient MyClass savedState;

     void saveState(MyClass savedState){
        this.savedState = savedState;
     }

}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>