使用触发器与JPA @PrePersist进行创建和更新时间戳的利弊

我正在构建一个新的Web应用程序,并且正在使用Spring,JPA /

Hibernate和Postgres。我的某些表具有creation_ts和lastupdate_ts列,它们是时间戳列,用于跟踪何时发生插入以及何时在行中进行最后更新。

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

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

这是我现在所拥有的解决方案,我有两个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;

}

}

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

这两种方法中哪一种更好?正如我所看到的,这是我个人对每种选择的利弊清单,我很高兴听到别人对这两种选择的经验。

选项A优点:

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

选项A的缺点:

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

选项B优点:

  1. 创建DDL时减少键入
  2. 插入和更新后无需从数据库中读取值
  3. 纯JPA注释,没有hibernate专用注释

选项B缺点:

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

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

回答:

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

您可以使用INSERT ... RETURNINGUPDATE ... RETURNING检索由触发器更改的值,因此无需执行其他SELECT。

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

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

以上是 使用触发器与JPA @PrePersist进行创建和更新时间戳的利弊 的全部内容, 来源链接: utcz.com/qa/417703.html

回到顶部