2 回答
TA贡献1865条经验 获得超7个赞
有很多方法可以实现这一目标。
@实体监听器
你可以有一个@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和@PreUpdateJPA 注释:
@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
}
并将Auditembeddable添加到实体中,如下所示:
@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
添加回答
举报