Учитывая объект, подобный следующему, вы можете отслеживать изменения в одном из его полей (сохраняя при этом и его первоначальное значение).
@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<String> 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\n", getOriginalField(), getField());
}
...
}
Если есть одна строка вбаза данных, подобная этой:
id: 1
field: a
version: 2011-12-02 11:24:00
до обновления поля (скажем, от a
до b
), вы получите следующий вывод.
Original: d, New: b
Исходное значение сохраняется, даже если сущность обновляется несколько раз, и оба состояния могут быть доступны через соответствующие методы получения ( getField и getOriginalField - вы можете стать более креативнымичем я в именовании:).
Таким образом, вы можете сэкономить на создании столбцов версий в своей базе данных, а также скрыть детали реализации от клиентов.
Вместо AtomicReferenceArray
вы можете использовать массивы, списки и т. д. для отслеживания всех изменений подобным образом.
Конечно, @PreUpdate
необязательно, но таким образом вы можете получать уведомления об изменениях в состоянии сущности и атомарно сохранятьTон обновил поля в файл.Есть и другие аннотации, подобные этим: см. Документацию для javax.persistence для других типов аннотаций.