Reputation: 194
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
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
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
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
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