问题: 如何检查用 注释的方法内哪些字段已更改@PreUpdate?
可选:如果上述问题的答案是“不可能,那么也许还有其他方法可以解决我的问题”
我希望modified Tourist每次更改其中的内容时自动更新的字段。
除了我们只修改的情况location。意味着如果我们location只改变——它应该被坚持,但modified不能改变。
已经存在的代码:
@Entity
public class Tourist {
private long id;
private String firstName;
private String lastName;
private Date created;
private Date modified;
private String location;
@PreUpdate
public void preUpdate() {
modified = new Date(); //PROBLEM : change modified even if only location field has been changed!
}
....
}
Run Code Online (Sandbox Code Playgroud)
更新:经过一些调查,我发现我可以在拦截器的帮助下解决它(扩展EmptyInterceptor):
public class TouristInterceptor extends EmptyInterceptor{
Session session;
private Set updates = new HashSet();
public void setSession(Session session) {
this.session=session;
}
public boolean onFlushDirty(Object entity,Serializable id,
Object[] currentState,Object[] previousState,
String[] propertyNames,Type[] types)
throws CallbackException {
if (entity instanceof Tourist){
if (somethingChangedExceptLocation())
updates.add(entity);
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
但这种方法的缺点是当您需要拦截单个实体时,会拦截所有内容。
更新的问题:
PreUpdateEvent包含新状态和旧状态有一个简单的非 JPA 解决方案,如下所示,但它确实有一些重复的代码,但当您没有太多字段时,这是一个解决方案:
@Entity
public class Tourist {
private long id;
private String firstName;
private String lastName;
private Date created;
private Date modified;
private String location;
public void setFirstName(String firstName){
if(! this.firstName.equals(firstName){
modified = new Date();
}
this.firstName = firstName;
}
public void setLastName(String lastName){
if(! this.lastName.equals(lastName){
modified = new Date();
}
this.lastName= lastName;
}
}
Run Code Online (Sandbox Code Playgroud)
否则,我会按照另一个答案中的建议,以稍微干净的方式保存加载时的先前状态。
@Entity
public class Tourist {
private long id;
private String firstName;
private String lastName;
private Date created;
private Date modified;
private String location;
@Transient
private Tourist previousState;
@PostLoad
public void setPreviousState() {
previousState = new Tourist();
//copy fields
}
@PreUpdate
public void preUpdate() {
if (isModified()) {
modified = new Date();
}
}
private boolean isModified() {
boolean modified = false;
if (!firstName.equals(previousState.firstName) {
modified = true;
}
//check other fields
return modified;
}
}
Run Code Online (Sandbox Code Playgroud)