Получение поля объекта предыдущее значение спящий JPA
Предположим, что у меня есть этот класс:
@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
сравнению с новым значением, которое собирается получить (обновлено) в базе данных. Я делаю это с предварительным 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();
Таким образом, это вызывает метод preUpdate
в mylistener и когда я пытаюсь:
MyClass.findById(someLongId);
Когда я отлаживаю, я уже получаю обновленный экземпляр, но обновление еще не произошло, потому что когда я проверяю базу данных в фамилии столбца, это все еще Dylan
.
Как получить значение из базы данных в моем методе preUpdate
а не в том, что я только что обновил?
Ответы
Ответ 1
Я думаю, что простой способ - сохранить предыдущее значение в переходной переменной, которая JPA не будет сохраняться. Поэтому просто введите переменную previousSurname и сохраните фактическое значение, прежде чем перезаписывать его в сеттере.
Если вы хотите сохранить несколько свойств, было бы легко, если бы ваш класс MyClass
был Serializable.
Если это так, добавьте прослушиватель после загрузки
public class MyClass implements Serializable {
@Transient
private transient MyClass savedState;
@PostLoad
private void saveState(){
this.savedState = SerializationUtils.clone(this); // from apache commons-lang
}
}
Но имейте в savedState
что savedState
является отдельным экземпляром.
Затем вы можете получить доступ к предыдущему состоянию в своем EntityListener
.
Вы также можете переместить PostLoad
слушателя к EntityListener
класса. Но тогда вам нужно получить доступ к поля savedState
. Я рекомендую сделать его либо с областью MyListener
пакета, либо с помощью пакета с расширенным MyListener
и поместить 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;
}
}