我的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();
哪个工作正常,但我想知道是否可以使用jpa / hibernate注释来进行此操作.我尝试了以下不同的选择:
@预更新
@PreUpdate
private void onUpdate(){
this.lastEditDate = new Date();
}
@UpdateTimestamp
@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
private Date lastEditDate;
但是我得到的是,当我更新一行时,所有行的时间戳都会更新,因此表中的所有时间戳始终是相同的.我在这里做错了什么?
解决方法:
有很多方法可以实现这一目标.
@EntityListener
如this article中所述,您可以使用@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());
}
}
您的实体将必须实现审核接口:
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
正如我在this article中所述,您还可以使用@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
}
然后将可嵌入的审计添加到实体,如下所示:
@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
}
休眠特定的@CreationTimestamp和@UpdateTimestamp
@CreationTimestamp
@Column(name = "created_on")
private Date createdOn;
@Column(name = "updated_on")
@UpdateTimestamp
private Date updatedOn;
而已!
现在,与您的评论有关:
But what I get is that when I update one row, the timestamps for all of the rows updated, so all of the timestamps in the table are always the same. What am I doing wrong here?
时间戳只会针对要修改的实体进行更新,而不会针对所有行进行更新.仅修改一行时,更新所有行的时间戳没有任何意义.否则,为什么要在行本身上显示该列?
SELECT MAX(updated_on)
FROM tags
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。