H2 内存数据库:使用 JDBC 设置时区?Java 单元测试

Pok*_*151 4 java jdbc h2

我在 h2 上遇到了一个奇怪的困境。我们有一个内存 h2 数据库设置,模式为 Oracle,以帮助我们进行单元测试。我们将应用程序的时区设置为

@PostConstruct
void started() {
    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
Run Code Online (Sandbox Code Playgroud)

我们将 h2 设置为 maven/springboot 应用程序中的数据源,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

我有一个基于时间戳的测试运行。所以我写了这个小映射器来从 h2 获取数据库时间:

@Select("Select CURRENT_TIMESTAMP")
String selectCurrentTimestamp();
Run Code Online (Sandbox Code Playgroud)

问题是 h2 不断获取其运行的实际系统时间,而不是监听上面列出的时区设置。因此,无论如何,我们的单元测试中的插入都会在正确的时间插入。但是基于时间的选择似乎是根据系统时间进行翻译的,因此无法正常工作。我还过渡到使用较新的java 8 java.time 类作为我的选择函数等的参数。仍然没有骰子。

我读过一些关于此问题的帖子,涉及休眠(未明确使用)和其他一些稍微类似的问题。但是我还没有找到解决这个特定问题的方法,并且可以使用一些帮助。

JDBC,这个问题的真正根源是谁?还是H2?根据这一点,我该如何开始修复它呢?我可以向 JDBC 连接 URL 提供一个字符串吗?或者要进行其他设置?

And*_*000 8

我遇到了同样的问题。让我走上正确道路的提示来自上一篇文章的答案

请注意,驱动程序加载后您将无法更改时区。

在 Application 类中使用 PostConstruct 已经太晚了。时区默认值将在驱动程序加载后设置,并且 H2 已被锁定。

有几个可以在这里使用的解决方案:

  1. 提供 JVM 参数来设置时区:-Duser.timezone=UTC
  2. 在加载 SpringApplication 之前(或加载其他任何内容之前)设置时区默认值:

    public static void main(String[] args) {
       TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
       SpringApplication.run(Application.class, args);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    注意:您还可以运行此命令来响应 ApplicationContextInitializedEvent,因为尚未加载其他 bean。我不确定在 Main 中这样做是否有任何缺点。