H2 in memory database not working after update to SpringBoot 2.4.0

Viewed 3609

I have an SpringBoot application with integrationtests utilising an H2 inmemory database. The tests work, if I use SpringBoot in versino 2.3.4.RELEASE. They fail if I upgrade to 2.4.0 with the following error:

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]: Invocation of init method failed; nested exception is java.lang.RuntimeException: Driver com.microsoft.sqlserver.jdbc.SQLServerDriver claims to not accept jdbcUrl, jdbc:h2:mem:integrationTestDB;DB_CLOSE_DELAY=-1;MODE=MSSQLServer;INIT=CREATE SCHEMA IF NOT EXISTS dbo\;SET SCHEMA dbo
Caused by: java.lang.RuntimeException: Driver com.microsoft.sqlserver.jdbc.SQLServerDriver claims to not accept jdbcUrl, jdbc:h2:mem:integrationTestDB;DB_CLOSE_DELAY=-1;MODE=MSSQLServer;INIT=CREATE SCHEMA IF NOT EXISTS dbo\;SET SCHEMA dbo

Here is my integration-test.properties, that is used by the tests:

spring.datasource.url=jdbc:h2:mem:integrationTestDB;\
  DB_CLOSE_DELAY=-1;\
  MODE=MSSQLServer;\
  INIT=CREATE SCHEMA IF NOT EXISTS dbo\\;SET SCHEMA dbo
spring.datasource.driver=org.h2.Driver
spring.datasource.hikari.driver-class-name=org.h2.Driver

hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.hbm2ddl.auto=none

spring.datasource.username=sa
spring.datasource.password=

spring.liquibase.user=sa
spring.liquibase.password=

The version of H2 is 1.4.200. The difference between success and failure is the SpringBoot version in the parent element of the pom:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
    </parent>

The liquibase version changed from 3.8.9 to 3.10.3. I configured it to stay at 3.8.9 but that didn't help.

I read the release notes and found the part about the embedded database detection: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.4-Release-Notes#embedded-database-detection

But adding

spring.datasource.initialization-mode=always

to the properties didn't help either.

I remember that it took some time to find the right datasource url last time, but I can't find any new clues with google.

Can you give me a hint, what causes this problem?

Kind regards, Ulrich

1 Answers

Your properties contain a mixture of H2 and SQL Server configuration. For example, you've configured an H2 JDBC URL for the DataSource but configured Hibernate to use SQLServerDialect. The exception shows that SQL Server's JDBC driver is being used when trying to initialise Liquibase. It looks to me like you're trying to use H2 in your integration tests, replacing SQL Server that's used when your app's deployed.

There's a new spring.liquibase.driver-class-name property in 2.4.0. When not set, it falls back to using spring.datasource.driver-class-name. There's no spring.datasource.driver property so try replacing the following two lines:

spring.datasource.driver=org.h2.Driver
spring.datasource.hikari.driver-class-name=org.h2.Driver

with the following line:

spring.datasource.driver-class-name=org.h2.Driver
Related