给定如下所示的实体,您可以跟踪其中一个字段的更改(同时也保留其原始值).
@Entity
@Table(schema = "test", name = "test")
public final class Test {
private static final int ORIGINAL = 0;
private static final int CURRENT = 1;
private Integer id;
// holds the original and current state of the field
private final AtomicReferenceArray field = new AtomicReferenceArray<>(2);
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Transient
public String getOriginalField() {
return field.get(ORIGINAL);
}
@Basic
public String getField() {
return field.get(CURRENT);
}
public void setField(String field) {
this.field.compareAndSet(ORIGINAL, null, field);
this.field.set(CURRENT, field);
}
@PreUpdate
public void preUpdate() {
System.out.format("Original: %s, New: %s
", getOriginalField(), getField());
}
...
}
如果这样的数据库中只有一行:
id: 1
field: a
version: 2011-12-02 11:24:00
在字段更新之前(例如,从a到b),您将获得以下输出.
Original: d, New: b
即使该实体被多次更新,原始值也将保留下来,并且可以通过相应的getter(getField和getOriginalField,在命名上您会比我更有创造力)来访问两种状态.
这样,您可以避免在数据库中创建版本列,也可以向客户端隐藏实现详细信息.
可以使用数组,列表等代替AtomicReferenceArray来跟踪所有更改,就像这样.
@PreUpdate当然不是必需的,但是通过这种方式,可以通知您实体状态的更改,并自动将更新的字段保存到文件中.还有更多类似这些的注释:有关其他注释类型,请参见javax.persistence的文档.