【发布时间】:2011-07-12 01:32:08
【问题描述】:
我正在构建一个新的 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 的缺点:
- 必须在插入和更新后进行选择以读取触发器放置的值。
- 我正在使用休眠注释来回读值
选项 B 优点:
- 创建 DDL 时减少输入
- 插入和更新后无需从数据库中读回值
- 纯 JPA 注释没有特定于休眠的注释
选项 B 的缺点:
- 集群中时钟偏差的危险
- JPA 提供者决定调用不可预测的回调方法时设置的字段
对于一个您可以完全控制数据库和 java 代码的新应用程序,您将如何解决这个问题。
【问题讨论】:
-
最后选择了什么解决方案?你有什么反馈。我正面临着这个问题:stackoverflow.com/questions/11136042/triggers-versus-jpa-event
标签: java hibernate postgresql jpa jpa-2.0