Mat*_*att 7 java postgresql timestamp hibernate jpa
我的 Postgres 数据库中有一个表,其中有一个时间戳列。我希望每次更新行时都会自动插入它。我写了一个数据库触发器:
CREATE FUNCTION update_last_edit_date() RETURNS trigger AS $update_last_edit_date$
BEGIN
NEW.last_edit_date := localtimestamp(0);
RETURN NEW;
END;
$update_last_edit_date$ LANGUAGE plpgsql;
CREATE TRIGGER update_last_edit_date BEFORE UPDATE ON employee
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE update_last_edit_date();
Run Code Online (Sandbox Code Playgroud)
效果很好,但我想知道是否有一种更简单的方法可以使用 jpa/hibernate 注释来做到这一点。我尝试了这些不同的选项:
@预更新
@PreUpdate
private void onUpdate(){
this.lastEditDate = new Date();
}
Run Code Online (Sandbox Code Playgroud)
@更新时间戳
@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
private Date lastEditDate;
Run Code Online (Sandbox Code Playgroud)
但我得到的是,当我更新一行时,所有行的时间戳都会更新,因此表中的所有时间戳始终相同。我在这里做错了什么?
有很多方法可以实现这一目标。
您可以存储@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
}
Run Code Online (Sandbox Code Playgroud)
这需要一个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());
}
}
Run Code Online (Sandbox Code Playgroud)
您的实体必须实现该Audit接口:
public interface Auditable {
Audit getAudit();
void setAudit(Audit audit);
}
Run Code Online (Sandbox Code Playgroud)
实体将如下所示:
@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
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常优雅的解决方案,因为它从主实体映射中提取审核逻辑。
@PrePersist和@PreUpdate您也可以使用@PrePersist和JPA 注释:@PreUpdate
@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
}
Run Code Online (Sandbox Code Playgroud)
并将可嵌入添加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
}
Run Code Online (Sandbox Code Playgroud)
@CreationTimestamp和@UpdateTimestamp@CreationTimestamp
@Column(name = "created_on")
private Date createdOn;
@Column(name = "updated_on")
@UpdateTimestamp
private Date updatedOn;
Run Code Online (Sandbox Code Playgroud)
就是这样!
现在,与您的评论相关:
但我得到的是,当我更新一行时,所有行的时间戳都会更新,因此表中的所有时间戳始终相同。我在这里做错了什么?
时间戳只会更新被修改的实体,而不是所有行。当仅修改单行时,更新所有行的时间戳是没有任何意义的。否则,为什么要在行本身上放置该列?
如果您想要最后修改时间戳,只需运行如下查询:
SELECT MAX(updated_on)
FROM tags
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3091 次 |
| 最近记录: |