我正在构建一个新的 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的优点:
- 数据库正在使用触发器进行更新,因此运行 Web 应用程序的集群中不存在时钟偏差的危险。
- 如果非 JPA 应用程序访问数据库,则强制要求保留这两列。
选项A的缺点:
- 必须在插入和更新后进行选择以读取触发器放置的值。
- 我正在使用 hibernate 注释来读回值
选项B的优点:
- 创建 DDL 时减少输入
- 插入和更新后无需从数据库读回值
- 纯 JPA 注释,没有 hibernate 特定注释
选项 B 的缺点:
- 集群中存在时钟偏差的危险
- 每当 JPA 提供者决定调用不可预测的回调方法时设置的字段
对于一个可以完全控制数据库和 Java 代码的新应用程序,您将如何解决这个问题。
必须在插入和更新后进行选择以读取触发器放置的值。
您可以使用INSERT ... RETURNING
or UPDATE ... RETURNING
检索触发器更改的值,因此无需执行另一个 SELECT。
除此之外,我想说这取决于你的环境。如果应用程序是关键任务,并且如果这些列维护不正确就会严重失败,那么我会坚持使用触发器。
如果这只是为了前端的方便(并且它可以优雅地处理由于不正确的值而导致的冲突),那么 JPA 方法可能更容易维护。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)