获取对象字段上一个值休眠 JPA

2022-09-01 20:58:45

让我们假设我有这个类:

@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);
  }
}

现在,在我的课程中,我试图找出以前的值实例与即将保存(更新)到数据库的新值。我用preupdate metdhod来做这件事:MyListenerMyClass

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

所以假设我有一个带有名字和姓氏的对象实例:MyClass

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

这没有被监听者拾取,这没关系,因为我只听更新。现在,如果我像这样更新这个实例:

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

因此,这会触发 mylistener 中的方法,当我尝试:preUpdate

MyClass.findById(someLongId);

当我调试时,我已经得到了新更新的实例,但更新尚未发生,因为当我签入列姓氏中的数据库时,它仍然是。Dylan

如何从方法中的数据库获取值,而不是从我刚刚更新的值中获取值?preUpdate


答案 1

我认为一个简单的方法是将以前的值保存在JPA不会保留的瞬态变量中。因此,只需引入一个变量presueSurname并保存实际值,然后再在设置器中覆盖它。

如果你想保存多个属性,如果你的类是MyClassSerializable.

如果是这样,请添加加载后侦听器

public class MyClass implements Serializable {

     @Transient
     private transient MyClass savedState;

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

}

但请注意,savedState 是一个分离的实例。

然后,您可以在 .EntityListener

还可以将侦听器移动到类。但是,您需要访问该字段。我建议让它要么包作用域,要么使用包作用域访问器,然后放入同一包中,PostLoadEntityListenersavedStateMyClassMyListener

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;
     }

}

答案 2