加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 获取对象字段以前的值hibernate JPA

发布时间:2020-12-14 05:48:12 所属栏目:Java 来源:网络整理
导读:我们假设我有这个课程: @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 nam
我们假设我有这个课程:
@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);
  }
}

现在在MyListener类中,我试图找出以前的MyClass实例值与即将被保存(更新)到数据库的新值.我这样做与preupdate metdhod:

@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方法中获取数据库的值,而不是我刚刚更新的值?

解决方法

我认为一个简单的方法是将以前的值保存在暂时变量中,JPA不会持久存在.
所以只需要介绍一个变量previousSurname并保存实际值,然后再在setter中覆盖它.

如果要保存多个属性,如果您的类MyClass是Serializable,那将很容易.

如果这样添加一个post load监听器

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中的上一个状态.

您也可以将PostLoad侦听器移动到EntityListener类.但是,您需要访问savedState字段.我建议将其作为范围限制或使用一个封装范围的访问器,并将MyClass和MyListener放在同一个包中,

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

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读