每当我使用JPA插入或更新实体时,我都想在数据库systimeamp
值上设置更新日期列。注意,我想使用数据库节点的时间,而不是应用程序服务器的时间。JPA或EcliseLink注释可以做到这一点吗?
一些JPA提供商支持这样的功能,遗憾的是Eclipselink不是其中之一。
幸运的是,自定义Eclipse Link属性转换器机制允许您在转换期间访问Session
,因此以下解决方法有效:
@Converter(name = "database-timestamp", converterClass = DatabaseTimestampFieldConverter.class)
@Entity
public class AuditedEntity {
@Id
@GeneratedValue
private Long id;
private String name;
...
@Convert("database-timestamp")
private Timestamp updatedDate;
@PreUpdate
protected void preUpdate() {
updatedDate = null; // needed to trigger the conversion; if you don't want the extra method here, use @EntityListeners instead
}
}
其中Database aseTimestampFieldConverter
定义为:
public class DatabaseTimestampFieldConverter implements Converter {
@Override
public Object convertObjectValueToDataValue(Object objectValue, Session session) {
return session.executeQuery(new ValueReadQuery("SELECT CURRENT_TIMESTAMP"));
}
@Override
public Object convertDataValueToObjectValue(Object dataValue, Session session) {
return dataValue;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public void initialize(DatabaseMapping mapping, Session session) {
}
}
或者,您可以尝试在文档中的审计示例之上构建。不过,它使用硬编码的数据库列名而不是字段级注释。
当然,使用您的数据库提供的机制(例如触发器)可能是一个更高性能的解决方案。
可以使用CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP
获取数据库时间