更新 Hibernate 中每一行的时间戳

我的 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

    @Temporal(TemporalType.TIMESTAMP)

    private Date lastEditDate;

但是我得到的是,当我更新一行时,所有行的时间戳都会更新,因此表中的所有时间戳始终相同。我在这里做错了什么?


缥缈止盈
浏览 158回答 2
2回答

莫回无

有很多方法可以实现这一目标。@实体监听器你可以有一个@Embeddable来存储审计属性:@Embeddablepublic 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 注释:@Embeddablepublic 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")@UpdateTimestampprivate Date updatedOn;就是这样!现在,与您的评论有关:但是我得到的是,当我更新一行时,所有行的时间戳都会更新,因此表中的所有时间戳始终相同。我在这里做错了什么?时间戳只会为被修改的实体更新,而不是为所有行更新。当只有一行被修改时,更新所有行的时间戳没有任何意义。否则,为什么要在行本身上放置该列?如果您想要上次修改时间戳,只需运行如下查询:SELECT MAX(updated_on)FROM tags
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java