触发器与 JPA @PrePersist 创建和更新时间戳的优缺点

2024-01-02

我正在构建一个新的 Web 应用程序,并且使用 Spring、JPA/Hibernate 和 Postgres。我的一些表具有creation_ts和lastupdate_ts列,它们是时间戳列,用于跟踪插入发生的时间以及行上最后一次更新发生的时间。

我还对表中的列使用命名约定,因此作为设计策略,每个表都保证有两列 pkey(整数代理键)和乐观锁定的版本。

我有两种方法可以使这些字段保持最新。

选项 A:使用触发器

这是我现在采用的解决方案,我有两个 Postgres 触发器,它们在插入和更新时触发,并使这些字段保持最新。我有两节课。

@MappedSuperclass
public abstract class PersistableObject
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="pkey")
    private Integer pkey;

    @Version
    @Column(name="version")
    private Integer version;

    public Integer getPkey()
    {
        return this.pkey;
    }

    public Integer getVersion()
    {
        return this.version;
    }
}

我有

@MappedSuperclass
public class TimeStampedPersistableObject extends PersistableObject {

    @Column(name = "creation_ts")
    @Temporal(TemporalType.DATE)
    @org.hibernate.annotations.Generated(value = GenerationTime.INSERT)
    private Date    creationTimestamp;

    @Column(name = "update_ts")
    @Temporal(TemporalType.DATE)
    @org.hibernate.annotations.Generated(value = GenerationTime.ALWAYS)
    private Date    updateTimestamp;

    public Date getCreationTimestamp()
    {
        return this.creationTimestamp;
    }

    public Date getUpdateTimestamp()
    {
        return this.updateTimestamp;
    }
}

选项 B:使用 JPA 侦听器

在此选项中,我将使用 JPA 侦听器来保持时间戳列最新。

我的问题:

这两种方法哪一种更好?正如我所看到的,这里是我个人列出的每个选项的优缺点,我对听到其他人对这两种选择的体验非常感兴趣。

选项A的优点:

  1. 数据库正在使用触发器进行更新,因此运行 Web 应用程序的集群中不存在时钟偏差的危险。
  2. 如果非 JPA 应用程序访问数据库,则强制要求保留这两列。

选项A的缺点:

  1. 必须在插入和更新后进行选择以读取触发器放置的值。
  2. 我正在使用 hibernate 注释来读回值

选项B的优点:

  1. 创建 DDL 时减少输入
  2. 插入和更新后无需从数据库读回值
  3. 纯 JPA 注释,没有 hibernate 特定注释

选项 B 的缺点:

  1. 集群中存在时钟偏差的危险
  2. 每当 JPA 提供者决定调用不可预测的回调方法时设置的字段

对于一个可以完全控制数据库和 Java 代码的新应用程序,您将如何解决这个问题。


必须在插入和更新后进行选择以读取触发器放置的值。

您可以使用INSERT ... RETURNING or UPDATE ... RETURNING检索触发器更改的值,因此无需执行另一个 SELECT。

除此之外,我想说这取决于你的环境。如果应用程序是关键任务,并且如果这些列维护不正确就会严重失败,那么我会坚持使用触发器。

如果这只是为了前端的方便(并且它可以优雅地处理由于不正确的值而导致的冲突),那么 JPA 方法可能更容易维护。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

触发器与 JPA @PrePersist 创建和更新时间戳的优缺点 的相关文章

随机推荐