我的应用程序和数据库都在 * America/Sao_Paulo * 时区。
数据库为Oracle 19c,应用程序使用:
- Spring2.7.8
- 休眠5.6.15.最终版
- java 11
我的问题是使用JPA实体将LocalDate或LocalDateTime保存到Oracle。
表列都使用 * DATE * 类型,如果将它们Map到 * LocalDate * 或 * LocalDateTime * 属性,就会出现问题。此问题仅在夏令时开始的日期出现。
假设我有两个属性:
@Column(name = "holiday1")
private LocalDate holiday1;
@Column(name = "holiday2")
private LocalDateTime holiday2;
...
entity.setHoliday1(LocalDate.of(2004, 11, 2));
entity.setHoliday2(LocalDateTime.of(2004, 11, 2, 0, 0, 0));
在这个例子中,2004 - 11 - 02是巴西DTS的开始,这一天没有午夜,所以Hibernate每次执行INSERT命令时都会将00:00时间部分更改为01:00,最后在数据库上得到2004 - 11 - 02 01:00:00。
我试着添加属性 * spring.jpa.properties. hib. jdbc. time_zone = UTC *,但没有任何效果。
如果我将属性的类型更改为 * OffsetDateTime * 并执行以下操作:
entity.setHoliday1(LocalDateTime.of(2004, 11, 2, 0, 0, 0).atOffset(ZoneOffset.UTC));
我在数据库中得到了2004 - 11 - 02 21:00:00,但是如果同时使用 * spring. jpa. properties. hib. jdbc. time_zone = UTC * 和 * OffsetDateTime *,Hibernate最终会在数据库中插入2004 - 11 - 02 00:00。
有没有办法让Hibernate忽略本地时区设置并正确处理LocalDate?我无法将应用程序的时区全局设置为UTC或将大量遗留代码更改为 * OffsetDateTime *。
1条答案
按热度按时间qacovj5a1#
Hibernate在绑定JDBC时通常会将
LocalDate
,LocalDateTime
等类型转换为java.sql.Date
,java.sql.Timestamp
等类型,原因是并非所有JDBC驱动程序都支持java.time类型。我不认为Hibernate会对
LocalDate
进行任何时区转换,因此如果传递给JDBC驱动程序的java.sql.Date
对象最终在数据库中进行了时区转换,这意味着JDBC驱动程序正在进行一些转换,请参阅Oracle文档。