Java 获取对象字段以前的值休眠 JPA
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19313629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting object field previous value hibernate JPA
提问by Gandalf StormCrow
Let's assume I have this class :
让我们假设我有这门课:
@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 my MyListener
class I'm trying to figure out the previous value MyClass
instance versus the new value that is about to get saved(updated) to database. I do this with preupdate metdhod :
现在在我的MyListener
课堂上,我试图找出以前的值MyClass
实例与即将保存(更新)到数据库的新值。我使用 preupdate 方法执行此操作:
@PreUpdate
public void preUpdate(Object entity) {
...some logic here...unable to get the old object value in here
}
So assuming I have a MyClass
objects instance with name and surname :
所以假设我有一个MyClass
带有 name 和 surname的对象实例:
MyClass mycls = new MyClass();
mycls.setName("Bob");
mycls.setSurname("Dylan");
mycls.save();
This wasn't picked up by listener which is ok because I'm listening only to updates. Now if I were to update this instance like so :
这不是由侦听器接收到的,这没关系,因为我只听更新。现在,如果我像这样更新这个实例:
MyClass cls = MyClass.findById(someLongId)
cls.setSurname("Marley");
cls.update();
So this triggers the preUpdate
method in mylistener and when I try to :
所以这会触发preUpdate
mylistener 中的方法,当我尝试:
MyClass.findById(someLongId);
When I debug I already get the newly updated instance but the update hasn't happened yet because when I check in database in column surname it's still Dylan
.
当我调试时,我已经获得了新更新的实例,但更新还没有发生,因为当我在列 surname 中检入数据库时,它仍然是Dylan
.
How do I get the value from database in my preUpdate
method and not the one I just updated?
如何从我的preUpdate
方法中的数据库中获取值而不是我刚刚更新的值?
采纳答案by René Link
I think an easy way is to save the previous value in a transient variable that JPA will not persist. So just introduce a variable previousSurname and save the actual value before you overwrite it in the setter.
我认为一种简单的方法是将先前的值保存在 JPA 不会持久化的瞬态变量中。所以只需引入一个变量 previousSurname 并在你在 setter 中覆盖它之前保存实际值。
If you want to save multiple properties it would be easy if your class MyClass
is Serializable.
如果你想保存多个属性,如果你的类MyClass
是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
}
}
But be aware that the savedState
is a detached instance.
但请注意,这savedState
是一个独立的实例。
You can then access the previous state in your EntityListener
.
然后,您可以访问EntityListener
.
You can also move the PostLoad
listener to the EntityListener
class. But then you need access to the savedState
field. I recommend to make it either package scoped or use a package scoped accessor and put MyClass
and MyListener
in the same package,
您还可以将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;
}
}