【发布时间】:2016-05-02 04:34:03
【问题描述】:
当关联的数据库服务器和应用程序服务器运行在不同的时区时,检索、持久化和更新应用程序服务器的当前时刻并不是一个好方法。应始终要求数据库服务器代替应用程序服务器提供当前时间。
因此,在中间层 JPA 本身上执行以下操作将是错误的方法。
Entity entity = new Entity();
entity.setTimestamp(new Timestamp(new java.util.Date().getTime()));
// Persist or merge the entity.
或者
Entity entity = new Entity();
entity.setLocalDateTime(java.time.LocalDateTime.now(ZoneOffset.UTC));
// Persist or merge the entity.
或者
Entity entity = new Entity();
entity.setZonedDateTime(java.time.ZonedDateTime.now(ZoneOffset.UTC));
// Persist or merge the entity.
或者
Entity entity = new Entity();
entity.setDateTime(org.joda.time.DateTime.now(org.joda.time.DateTime.DateTimeZone.UTC));
// Persist or merge the entity.
等以及insertable = false, updatable = false 用于实体中的相应字段。
JPA 允许从数据库服务器检索日期时间/时间戳。
javax.persistence.criteria.CriteriaBuilder#Expression<Date> currentDate()javax.persistence.criteria.CriteriaBuilder#Expression<Time> currentTime()javax.persistence.criteria.CriteriaBuilder#Expression<Timestamp> currentTimestamp()
当然,JPQL 也是如此。
但是 JPA 似乎无法通过将持久化和合并当前时间的任务委托给数据库服务器本身来持久化和合并数据库服务器本身的当前时间。
我对使用@Version 装饰日期时间相关字段不感兴趣,因为它具有完全不同的目的,即在中间层 JPA 本身中获取行级乐观锁(反过来,使用时间戳本身的乐观锁也会受到某些问题的影响)特殊缺点)。
在中间层使用持久性提供程序时,我不太考虑 RDBMS 丛林。
所以,除了像 CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 这样的 RDBMS 所遵循的功能外,JPA 或特定的持久性提供程序本身是否有一种方法来处理数据库服务器的当前时间,用于两个幂等操作,即“持久”和“合并” “?
我目前关心的是 Hibernate 和 EclipseLink。
【问题讨论】:
-
不应该
Dateclass 和 jdbc driver 处理时区差异吗?你为什么要为此烦恼? -
这可能发生,如果数据库服务器和 EE 服务器/Servlet 容器都精确地运行在同一个时区(毫秒或秒的差异仍然可能)。然而,如果他们位于不同的时区,故事将完全改变。如果选择应用服务器的当前时间,依赖于当前时刻的数据库操作将严重失败。
-
不,如果您正确使用
Dates,他们不应该这样做。你试过了吗? -
例如,不同的应用服务器运行在不同的时区,如果试图访问一个普通的数据库服务器,如果应用服务器负责提交当前时间,那么当前时间被插入到数据库中根据应用程序服务器运行的不同时区而有所不同。在这些应用程序服务器中处理数据时间的 Java API 将根据它们使用的时区提交不同的时间。
-
又错了。日期只不过是一个数字。时区(以及夏令时)仅在将该数字格式化为表示日期的文本时使用。你试过了吗?
标签: hibernate datetime jpa time timestamp