我遇到了h2的怪异难题。我们有一个内存h2 db设置,模式为Oracle,以帮助进行单元测试。 我们已将应用程序的时区设置为
@PostConstruct
void started() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
我们将m2 / springboot应用程序中的h2设置作为数据源,如下所示:
datasource.config.url=jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=ORACLE;
datasource.config.username=sa
datasource.config.password=
datasource.config.driver-class-name=org.h2.Driver
我有一个基于时间戳的测试。所以我写了这个小映射器来从h2获取数据库时间:
@Select("Select CURRENT_TIMESTAMP")
String selectCurrentTimestamp();
问题在于,h2会继续获取其运行时的实际系统时间,而不是听上面列出的时区设置。因此,无论如何,在我们的单元测试中插入都是在正确的时间插入。但是基于时间的选择似乎是根据系统时间转换的,因此无法正常工作。我也已经过渡到使用 new java 8 java.time类作为选择函数等的参数。
关于此问题,我已经阅读了很多有关休眠(未明确使用)的帖子以及其他一些类似的问题。但是,我尚未找到解决此特定问题的解决方案,可以寻求帮助。
JDBC的真正来源是谁?还是H2?并据此,如何开始进行修复?我可以提供给JDBC连接URL的字符串吗?还是要进行其他设置?
答案 0 :(得分:2)
我遇到了同样的问题。使我走上正确道路的提示来自this answer on a previous post:
请注意,加载驱动程序后无法更改时区。
在Application类中使用PostConstruct为时已晚。加载驱动程序后,将设置默认时区,并且H2已被锁定。
可以在此处使用的几种解决方案:
在加载SpringApplication之前(或在加载任何其他内容之前)设置时区默认值:
public static void main(String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SpringApplication.run(Application.class, args);
}
注意:您还可以运行此命令来响应ApplicationContextInitializedEvent,因为尚未加载任何其他bean。我不确定在Main中执行此操作是否有任何弊端。