我遇到了 h2 的奇怪困境。我们有一个内存中的 h2 数据库设置,模式类似于 Oracle,以帮助我们进行单元测试。 我们已将应用程序的时区设置为
@PostConstruct
void started() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
我们在 maven/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 一直使用它正在运行的实际系统时间,而不是听上面列出的时区设置。因此,无论如何,在我们的单元测试中插入都会在正确的时间插入。但是基于时间的选择似乎是根据系统时间进行翻译的,因此无法正常工作。我也已经过渡到使用 更新的 java 8 java.time 类作为我的选择函数等的参数。仍然没有骰子。
我已经阅读了很多关于此的帖子,其中涉及 hibernate (未明确使用)和其他一些稍微类似的问题。但是,我还没有找到解决这个特定问题的方法,需要一些帮助。
谁才是这个问题的真正根源,JDBC?还是H2?并且取决于此,我怎样才能开始修复它呢?我可以向 JDBC 连接 URL 提供一个字符串吗?还是要进行其他设置?
最佳答案
我遇到了同样的问题。让我走上正确道路的提示来自 this answer on a previous post :
Note that you can't change the timezone after the driver has been loaded.
在 Application 类中使用 PostConstruct 为时已晚。加载驱动程序后将设置时区默认值,并且 H2 将被锁定。
一些可以在这里工作的解决方案:
- 提供一个 JVM arg 来设置时区:-Duser.timezone=UTC
在加载 SpringApplication 之前(或在加载任何其他内容之前)设置默认时区:
public static void main(String[] args) { TimeZone.setDefault(TimeZone.getTimeZone("UTC")); SpringApplication.run(Application.class, args); }
注意:您还可以运行它以响应 ApplicationContextInitializedEvent,因为尚未加载其他 bean。我不确定仅在 Main 中执行此操作是否有任何缺点。
关于java - H2 内存 DB : Set Timezone with JDBC? Java 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52786770/