我正在构建一个新的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 = Generathtml" target="_blank">ionTime.ALWAYS)
private Date updateTimestamp;
public Date getCreationTimestamp()
{
return this.creationTimestamp;
}
public Date getUpdateTimestamp()
{
return this.updateTimestamp;
}
}
选项B:使用JPA侦听器
在此选项中,我将使用JPA侦听器将列的时间戳记保持最新。
我的问题:
这两种方法中哪一种更好?正如我所看到的,这是我个人对每种选择的利弊清单,我很高兴听到别人对这两种选择的经验。
选项A优点:
选项A的缺点:
选项B优点:
选项B缺点:
对于将完全控制数据库和Java代码的新应用程序,您将如何解决该问题。
在插入和更新后必须进行选择以读取触发器放置的值。
您可以使用INSERT ... RETURNING
或UPDATE ... RETURNING
检索由触发器更改的值,因此无需执行其他SELECT。
除此之外,我会说这取决于您的环境。如果应用程序是关键任务,并且如果这些列的维护不正确,将导致惨败,那么我会坚持使用触发器。
如果这只是为了前端的方便(并且可以优雅地处理由于不正确的值引起的冲突),那么JPA方法可能更易于维护。
问题内容: 对于某些Hibernate实体,我们需要存储其创建时间和上次更新时间。你将如何设计? 你将在数据库中使用什么数据类型(假设使用MySQL,可能与JVM时区不同)?数据类型是否支持时区? 你会在Java中使用什么数据类型(Date,Calendar,long,…)? 你将由谁负责设置时间戳(数据库,ORM框架(hibernate)或应用程序程序员)? 你将使用哪些注释进行映射(例如@Te
问题内容: 我在玩JPA(具体来说是Eclipselink)。下面的实体具有一个时间戳,应该在该实体上次更新时反映该时间戳。 每次更改此实体时,使JPA自动更新该时间戳的策略是什么? 如果我还想要一个“创建”时间戳记,该时间戳记仅在实体首次保留时设置,而永远不允许再次更改,该怎么办? 问题答案: 使用@PrePersist和@PreUpdate批注并编写您自己的事件侦听器。 详细了解一下此答案。它
问题内容: 我想创建一个MySQL触发器,该触发器每次在不同表中的datetime行之一达到比现在低的datetime时更新一个表。 我将如何完成? 那有可能吗? 为了显示: 因此,当时间过去并变成时,我希望计数器增加1。 问题答案: 您应该能够使用触发器和事件调度程序来执行此操作: -在每次更新/插入时均在表上创建触发器 -该触发器创建在行的日期时间发生的已调度事件,并更新第二个表
问题内容: 如何从MongoDB集合中的时间(HH:MM:SS.Milisecond)值大于零的日期字段中选择记录,并通过保持日期的时间(HH:MM:SS)值为零来更新记录值是否与Python脚本中的现有值相同? 当前数据如下所示- 如何在Python脚本中仅选择第4、5、6和7行,并使用时间戳将其更新为零? 更新后,数据如下所示- 问题答案: 最好的方式来更新您的文件,并在时间使用日期时间模块,
我正在使用Spring Cloud Sleuth和Zipkin(通过HTTP),将spring-cloud-starter-zipkin版本2.0.0.M6添加到我的依赖项(基于Spring Boot 2.0.0.rc1和Spring Cloud Finchley M6)中。 我正在使用@Newspan注释来标记某个(昂贵的)操作的子跨度。当跨度信息发送到Zipkin时,我注意到缺少子跨度的时间戳
问题内容: 我知道我可以使用它来创建DDL创建触发器; 问题在于,该触发器将在“创建序列”之类的DDL上运行;如何仅对“创建表” DDL执行此操作? 问题答案: CREATE OR REPLACE TRIGGER create_table_trigger AFTER CREATE ON SCHEMA BEGIN IF SYS.DICTIONARY_OBJ_TYPE = ‘TABLE’ THEN .