【发布时间】:2019-01-22 13:40:16
【问题描述】:
我已经在 StackOverflow 上多次看到过这个问题,而且大多数情况下都是带有 Spring Boot 配置的 Spring Boot 应用程序。我已按照所有步骤操作,但我仍然遇到此问题。如果我不能很快解决这个问题,我将不得不回到旧的 java.util.Date 以便将我的数据持久保存到数据库中......至少它没有问题。所以,我有一个 Spring 5.1.2.Release 应用程序,带有 Hibernate 5.4.0.Final、hibernate-java8 依赖项和最新的 MySQL 连接器 8.0.13。
我从之前的帖子和网络上的其他文章中了解到,如果数据库设置为 UTC,但应用程序在另一个时区运行,在我的情况下为 GMT-5 为 EST,则可能会弹出此问题。
所以,这里是技术细节: 我的 MySQL 连接如下所示:
hibernate.connection.url=jdbc:mysql://localhost:3306/my_db?
serverTimezone=UTC&useLegacyDatetimeCode=false&useTimezone=true
连接字符串,在applicationContext.xml中使用:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>${hibernate.connection.driver.class}</value>
</property>
<property name="url">
<value>${hibernate.connection.url}</value>
</property>
<property name="username">
<value>${hibernate.connection.username}</value>
</property>
<property name="password">
<value>${hibernate.connection.password}</value>
</property>
</bean>
我的 applicationContext.xml 中的 Hibernate 属性如下所示:
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_reflection_optimizer}</prop>
<prop key="useUnicode">true</prop>
<prop key="useLegacyDatetimeCode">false</prop>
<prop key="serverTimezone">UTC</prop>
<prop key="useTimezone">true</prop>
<prop key="hibernate.jdbc.time_zone">UTC</prop>
</props>
</property>
我的 Maven 依赖项是:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-java8</artifactId>
<version>5.4.0.Final</version>
</dependency>
我的实体代码很简单:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "transaction_id")
private long txId;
@Column(name = "transaction_date")
private LocalDate txDate;
我像这样将代码保存到数据库中:
@Override
public TxEntity create(TxEntity txEntity)
{
this.sessionFactory.getCurrentSession().save(txEntity);
this.sessionFactory.getCurrentSession().flush();
this.sessionFactory.getCurrentSession().refresh(txEntity);
return txEntity;
}
数据库在 MySQL 中将“transaction_date”作为 DATE 字段。
我的单元测试显示我可以新建一条记录,我设置的日期如下:
LocalDate today = LocalDate.now();
我坚持记录,当我测试时:
assertEquals(today, myRecord.getTransactionDate());
这失败了,因为我得到了上一个日期。
我认为如果我使用最新版本的 Hibernate 和 Hibernate-java8 就可以了,但事实并非如此。我想如果我引入最新的 JPA2.2 会起作用,但事实并非如此。所以,我认为我做的一切都是正确的,但我仍然有一个问题。
所以,如果您有什么需要看的,请告诉我,我可以添加。我认为我做的一切都是正确的,但如果有什么问题需要解决,请告诉我。当然,我自己会继续关注这个。
【问题讨论】:
-
Spring 4 并未正式支持 Hibernate 5.4 (afaik),因此您可能需要重新考虑。自 hibernate 5.2 以来,
java8类型也是hibernate-core的一部分,因此您不需要额外的依赖项。您设置了hibernate.connection.url,但我没有看到您使用此 URL 的任何地方。如果您使用它来配置休眠以使用连接但还注入手动配置的数据源,则该设置几乎什么都不做。简而言之,配置信息太少,无法查看您是否配置正确。 -
我也错过了在您的休眠配置中将
hibernate.jdbc.time_zone属性设置为UTC。另见vladmihalcea.com/… -
@M.Deinum 我刚刚添加了我使用连接字符串的位置,它就在 applicationContext.xml 文件中......你看不到还有什么可能有帮助。我总是可以将此应用程序移至 Spring 5 ...我不是 Spring Boot 的粉丝。
-
属性名称具有误导性。尽管如此,你应该在你的休眠属性中拥有
hibernate.jdbc.time_zone属性,但这是缺失的。请参阅我之前评论中的链接文章,它解释了所有这些。 -
@M.Deinum 我的错误,这不是 Spring Boot,而是使用 Spting 5.1.2.Release
标签: mysql spring hibernate java-8 jpa-2.0