Есть много способов достичь этой цели.
@ EntityListener
Как объяснено в этой статье , вы можете иметь @Embeddable
для хранения свойств аудита:
@Embeddable
public class Audit {
@Column(name = "created_on")
private LocalDateTime createdOn;
@Column(name = "updated_on")
private LocalDateTime updatedOn;
//Getters and setters omitted for brevity
}
Для которого требуется EntityListener
, который выглядит следующим образом:
public class AuditListener {
@PrePersist
public void setCreatedOn(Auditable auditable) {
Audit audit = auditable.getAudit();
if(audit == null) {
audit = new Audit();
auditable.setAudit(audit);
}
audit.setCreatedOn(LocalDateTime.now());
}
@PreUpdate
public void setUpdatedOn(Auditable auditable) {
Audit audit = auditable.getAudit();
audit.setUpdatedOn(LocalDateTime.now());
}
}
Вам необходимо будет реализовать интерфейс Audit
:
public interface Auditable {
Audit getAudit();
void setAudit(Audit audit);
}
И объекты будут выглядеть следующим образом:
@Entity(name = "Tag")
@Table(name = "tag")
@EntityListeners(AuditListener.class)
public class Tag implements Auditable {
@Id
private String name;
@Embedded
private Audit audit;
//Getters and setters omitted for brevity
}
Это очень элегантное решение, поскольку оно извлекает логику аудита из отображения основного объекта.
@PrePersist
и @PreUpdate
Как я объяснил в этой статье , вы также можете использовать аннотации @PrePersist
и @PreUpdate
JPA:
@Embeddable
public class Audit {
@Column(name = "created_on")
private LocalDateTime createdOn;
@Column(name = "updated_on")
private LocalDateTime updatedOn;
@PrePersist
public void prePersist() {
createdOn = LocalDateTime.now();
}
@PreUpdate
public void preUpdate() {
updatedOn = LocalDateTime.now();
}
//Getters and setters omitted for brevity
}
и добавить встраиваемое Audit
для сущности, подобной этой:
@Entity(name = "Tag")
@Table(name = "tag")
public class Tag {
@Id
private String name;
@Embedded
private Audit audit = new Audit();
//Getters and setters omitted for brevity
}
для Hibernate * @CreationTimestamp
и @UpdateTimestamp
@CreationTimestamp
@Column(name = "created_on")
private Date createdOn;
@Column(name = "updated_on")
@UpdateTimestamp
private Date updatedOn;
Вот и все!
Теперь, связанные с вашим комментарием:
Но что я получаю, так это то, что при обновлении одной строки обновляются метки времени для всех строк, поэтому все метки времени в таблицеспособы одинаковые.Что я здесь не так делаю?
Отметка времени будет обновляться только для изменяемой сущности, а не для всех строк.Не имеет смысла обновлять временную метку всех строк, когда изменяется только одна строка.В противном случае, зачем вам этот столбец в самой строке?
Если вы хотите использовать метку времени последнего изменения, просто запустите такой запрос:
SELECT MAX(updated_on)
FROM tags