Search code examples
spring-booth2flyway

Flyway H2 and MySql mismatch after upgrading


I got myself in a deep mud :(

I wanted to upgrade gradle from 4 to 6. This caused me upgrading spring, and eventually flyway and H2.

Now, unfortunantly, I get flyway errors on tests.

Here is some info:

 api "org.springframework.boot:spring-boot-starter-json:2.2.2.RELEASE"
api "org.springframework.boot:spring-boot-starter-web:2.2.2.RELEASE"
    api "org.springframework.boot:spring-boot-starter-data-jpa:2.2.2.RELEASE"
testImplementation("org.springframework.boot:spring-boot-starter-test:2.2.2.RELEASE") {
    exclude (group: 'com.h2database', module: 'h2')
}

api("mysql:mysql-connector-java:5.1.38")
implementation 'org.flywaydb:flyway-core:6.4.2'
testImplementation("com.h2database:h2:1.4.199") {
  force = true
}

Before the upgrade, all worked fine. Now I get weird WARN about another version (though I am using the recommended) version, and lots or errors.:

 WARN  o.f.c.i.d.b.Database:53 - Flyway upgrade recommended: H2 1.4.200 is newer than this version of Flyway and support has not been tested. The latest supported version of H2 is 1.4.199.

ERROR o.f.c.i.c.DbMigrate:57 - Migration of schema "PUBLIC" to version 9 - fixCheckingAccountIndex failed! Please restore backups and roll back database and code!


SQL State  : 42S22
Error Code : 42122
Message    : Column "INDEX" not found; SQL statement:
ALTER TABLE table1 DROP INDEX ACC_INDEX [42122-200]
Location   : db/migration/V9__fixAccountIndex.sql 
Line       : 1
Statement  : ALTER TABLE checking_account DROP INDEX BTA_CHECKING_ACC_INDEX

test-properties:

spring.jpa.hibernate.ddl-auto=none
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE;INIT=create schema if not exists \\"public\"\\; SET SCHEMA public;
spring.datasource.username=root
spring.datasource.password=root

When I run the application normally, with no tests, it all works fine.

Any ideas?

Thanks and Regards,

EDIT

I've been trying to understand why I get version 200 of h2.

On my depndecy tree:

gradle -q dependencies | grep h2
+--- com.h2database:h2:1.4.199 (n)
|    |    |         +--- com.h2database:h2:1.4.193 -> 1.4.200
+--- com.h2database:h2:1.4.199 -> 1.4.200
|    |    |         +--- com.h2database:h2:1.4.193 -> 1.4.200
+--- com.h2database:h2:1.4.199 -> 1.4.200
|    |    |         +--- com.h2database:h2:1.4.193 -> 1.4.200
+--- com.h2database:h2:1.4.199 -> 1.4.200
|    |    |         +--- com.h2database:h2:1.4.193 -> 1.4.200
+--- com.h2database:h2:1.4.199 -> 1.4.200

From some reason it uses the newer verison.

EDIT 2020-05-26

As reqeusted here is the error after upgrading to spring 2.3.0

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flyway' defined in com...SpringTestConfiguration: Invocation of init method failed; nested exception is org.flywaydb.core.internal.command.DbMigrate$FlywayMigrateException: 
Migration V9__IndexFix.sql failed
------------------------------------------------
SQL State  : 42S22
Error Code : 42122
Message    : Column "INDEX" not found; SQL statement:
ALTER TABLE table1 DROP INDEX ACC_INDEX [42122-200]
Location   : db/migration/V9__IndexFix.sql (.../resources/db/migration/V9__IndexFix.sql)
Line       : 1
Statement  : ALTER TABLE table1 DROP INDEX ACC_INDEX

The warnings of the compatibility which I complained at this post, are gone after the upgrade

Still this h2 error. on older versions it worked. current versions:

org.flywaydb:flyway-core:6.4.1 (though in gradle I put 6.4.2) com.h2database:h2:1.4.200


Solution

  • Update your Spring Boot dependencies to 2.3.0.RELEASE.

    The 2.2.X had a dependency mismatch between an old flyway version (6.0.8) and an unsupported new H2 version (1.4.200).
    Support for H2 1.4.200 came with Flyway 6.1.0.

    And even if you specify a newer Flyway version - I think it is as ignored as the specified H2 version.

    Edit:
    Alternatively you can force specific versions in Gradle like this:

    allprojects {
        configurations.all {
            resolutionStrategy {
                dependencySubstitution {
                    substitute module('com.h2database:h2') with module('com.h2database:h2:1.4.199')
                }
            }
        }
    }