当前位置: 首页 > 面试题库 >

使对象字段先前的值休眠JPA

阮梓
2023-03-14
问题内容

假设我有这个课:

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

因此,这会触发preUpdatemylistener中的方法以及当我尝试执行以下操作时:

MyClass.findById(someLongId);

当我调试时,我已经获得了新近更新的实例,但是更新尚未发生,因为当我在“姓”列中检入数据库时​​,它仍然是Dylan

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


问题答案:

我认为一种简单的方法是将先前的值保存在JPA将不会持久的瞬态变量中。因此,只需引入一个变量previousSurname并保存实际值,然后再在设置器中将其覆盖即可。

如果要保存多个属性,如果您的班级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

您也可以将PostLoad侦听器移至EntityListener该类。但是随后您需要访问该savedState字段。我建议,使其无论是封装作用域或使用包范围的访问,并把MyClassMyListener在同一个包,

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

}


 类似资料:
  • 问题内容: 我试图找出是否可以使用Hibernate Criteria API进行以下HQL: 其中InitialCount是一个非常简单的,具有字符串和长构造函数的bean: 可能吗? 问题答案: 试试这个 : 其中,公式属性是映射到公式“ substring(name,1,1)”的人员的属性

  • 问题内容: 我面临的问题是Hibernate的一个简单问题,但无法解决(无法访问的Hibernate论坛当然无济于事)。 我有一个简单的课程想继续学习,但是请继续学习: 持久化类的相关代码为: 实际的运行代码很简单: 我在注解中尝试了一些“策略”,但似乎不起作用。初始化也无济于事!(例如)。 谁能给我一些启示? 编辑2: 确认:不能解决问题 求助: 重新创建数据库解决了问题 问题答案: 有时,即使

  • 问题内容: 我有一个实体,其(字符串)字段的大小为10 但是,字段的值长度可以为5或10。我想根据其长度创建一个与该字段的值匹配的hibernate条件,例如: 但是…上面看起来不错,但是显然不起作用。我不知道该如何处理。我将不胜感激。 谢谢 //解决方案(感谢Stanislav!)实体: 条件: 问题答案: 您可以引入人工的Entity字段codeLength并使用@Formula注释(此处为示

  • 问题内容: 我在设置字符串类型时遇到麻烦,就像 而且它没有用,我检查了mysql模式,它仍然是varchar(255),我也尝试过, 要么 我正在尝试将类型设为TEXT,任何想法将不胜感激! 问题答案: 您说“我检查了mysql模式,它仍然是varchar(255)”-您是否希望Hibernate自动更改数据库?不会的 即使您已经设置,我也不相信Hibernate会改变现有的列定义。 如果要生成新

  • 问题内容: 我在JPA中更新对象时遇到问题 我有豆子用户 和 当尝试更新时给我异常:当表评级包含行时,无法通过反射获得字段值 错误TransactionInterceptor:434-应用程序异常被提交异常com.vodafone.visradio.dataaccess.exception.DataAccessException覆盖:org.hibernate.PropertyAccessExce

  • 问题内容: 在合理的时间内从数据库中完全加载非常复杂的对象以及合理的查询数量时,我遇到了问题。 我的对象有很多嵌入式实体,每个实体都引用了另一个实体,另一个实体又引用了另一个,依此类推(因此,嵌套级别为6) 因此,我创建了示例来演示我想要的内容:https : //github.com/gladorange/hibernate-lazy- loading 我有用户。 用户有喜欢的 橙子,苹果,葡萄