Cynan
Cynan

Reputation: 194

Spring Boot 2.7.0 Liquibase fails with "Migration files for change set"

I was using Spring Boot 2.6.8 along with Liquibase which works fine. This is used with a MySQL database when running in production. For integration tests we run it against a H2 in memory database.

Since upgrading to SB 2.7.0, which switches out H2 v1.4.200 to v2.1.212, Liquibase then fails with the H2 in memory database.

Exception encountered during context initialization - cancelling refresh attempt: 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 liquibase.exception.LiquibaseException: liquibase.exception.MigrationFailedException: Migration failed for change set changelog/0.3.0/tables/file_type.xml::1437572803912-1::bobd (generated):
Reason: liquibase.exception.DatabaseException: Syntax error in SQL statement "CREATE TABLE PUBLIC.FILE_TYPE (ID INT[*](10) GENERATED BY DEFAULT AS IDENTITY NOT NULL, NAME VARCHAR(45) NOT NULL, CONSTRAINT PK_FILE_TYPE PRIMARY KEY (ID))";
expected "ARRAY, INVISIBLE, VISIBLE, NOT, NULL, AS, DEFAULT, GENERATED, ON, NOT, NULL, AUTO_INCREMENT, DEFAULT, NULL_TO_DEFAULT, SEQUENCE, SELECTIVITY, COMMENT, CONSTRAINT, COMMENT, PRIMARY, UNIQUE, NOT, NULL, CHECK, REFERENCES, AUTO_INCREMENT, ,, )";
SQL statement: CREATE TABLE PUBLIC.FILE_TYPE (ID INT(10) GENERATED BY DEFAULT AS IDENTITY NOT NULL, NAME VARCHAR(45) NOT NULL, CONSTRAINT PK_FILE_TYPE PRIMARY KEY (ID)) [42001-212] 
[Failed SQL: (42001) CREATE TABLE PUBLIC.FILE_TYPE (ID INT(10) GENERATED BY DEFAULT AS IDENTITY NOT NULL, NAME VARCHAR(45) NOT NULL, CONSTRAINT PK_FILE_TYPE PRIMARY KEY (ID))]

Now Liquibase should be able to map our changelog to MySQL or H2 (or any other DB) fine right? So I'm thinking this is an issue with Liquibase not support H2 v2.x properly? Or perhaps there is a property that I've missed that now needs setting?

TIA.

Upvotes: 10

Views: 9203

Answers (4)

Cynan
Cynan

Reputation: 194

For completeness, I recreated an example bug for this on the Liquibase Github repo. and it has since been fixed by the developers.

Upvotes: 0

jfk
jfk

Reputation: 5287

I had this issue and fixed by downgrading the h2 to a lower version

testImplementation 'com.h2database:h2:1.4.200'

Another solution is what is discussed in the H2 Google Group, where the h2 engine mode.limit is set in the dataSource bean

@TestConfiguration
public class DataSourceTestConfig {

    @Bean
    public DataSource dataSource() {
        // Fix for the H2 2.x issue with spring boot 2.7.
        org.h2.engine.Mode mode = org.h2.engine.Mode.getInstance("Oracle");
        mode.limit = true;
        return new EmbeddedDatabaseBuilder() //
                .setType(H2) //
                .setName("testdb-h2;MODE=Oracle") //
                .ignoreFailedDrops(true) //
                .build();
    }

}

Upvotes: 2

Ramon10
Ramon10

Reputation: 39

I got the same error using a MS SQL Server database, I resolved issue by configuring hibernate dialect and H2 in SQL Server Mode in the application.properties file in the test resources folder.

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2016Dialect
spring.datasource.url=jdbc:h2:mem:testdb;MODE=MSSQLServer

Or you can disable liquibase and allow the tables to be auto-generated spring.liquibase.enabled=false

Upvotes: 2

Yegor
Yegor

Reputation: 81

I've got the similar error upon migration to the Spring Boot 2.7.0. In my case it concerned the new H2 reserved word 'value'. I guess, in your case the problem is in the token (10) after INT.

Here is quotation for the section H2 2.1 from the Spring Boot doc:

Spring Boot 2.7 has upgraded to H2 2.1.120. H2 2.x is backwards incompatible and fixes a number of security vulnerabilities. See the H2 changelog and migration guide for details of the changes and how to handle the upgrade.

Upvotes: 5

Related Questions