javaspringspring-bootflyway

How to run Java-based Flyway Migration in Spring Boot?


I have been trying to make Java-based Flyway Migration run properly in Spring Boot for about 10 hours but even after countless effort and searching, nothing has worked so far.

Here is the Java-based migration that I want to run. Please note I now it can be run using SQL, but I need Java-based migration to work so that I can perform more complex tasks later.

package db.migration.kotlin

import org.flywaydb.core.api.migration.BaseJavaMigration
import org.flywaydb.core.api.migration.Context


class V1__create_users_table : BaseJavaMigration() {
    override fun migrate(context: Context) {
        context.connection.use { connection ->
            connection.createStatement().execute("""
            CREATE TABLE users
            (
                id         SERIAL NOT NULL,
                email      TEXT   NOT NULL,
                created_at TIMESTAMP
            );
            """
            )
        }
    }

}

This is currently placed under src/main/resources/db/migration/kotlin.

When I run the Spring Boot application, here is what I see in the logs:

2024-05-12T00:16:23.743+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.c.i.s.SchemaHistoryFactory           : Default schema: null
2024-05-12T00:16:23.747+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.c.i.c.SqlScriptCallbackFactory       : Scanning for SQL callbacks ...
2024-05-12T00:16:23.747+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.scanner.Scanner        : Filtering out resource: db/migration/kotlin/V2__update_created_at.kt (filename: V2__update_created_at.kt)
2024-05-12T00:16:23.747+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.scanner.Scanner        : Filtering out resource: db/migration/kotlin/V1__create_users_table.kt (filename: V1__create_users_table.kt)
2024-05-12T00:16:23.752+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.command.DbValidate     : Validating migrations ...
2024-05-12T00:16:23.753+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.scanner.Scanner        : Filtering out resource: db/migration/kotlin/V2__update_created_at.kt (filename: V2__update_created_at.kt)
2024-05-12T00:16:23.753+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.scanner.Scanner        : Filtering out resource: db/migration/kotlin/V1__create_users_table.kt (filename: V1__create_users_table.kt)
2024-05-12T00:16:23.753+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.scanner.Scanner        : Filtering out resource: db/migration/kotlin/V2__update_created_at.kt (filename: V2__update_created_at.kt)
2024-05-12T00:16:23.753+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.scanner.Scanner        : Filtering out resource: db/migration/kotlin/V1__create_users_table.kt (filename: V1__create_users_table.kt)
2024-05-12T00:16:23.753+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.scanner.Scanner        : Filtering out resource: db/migration/kotlin/V2__update_created_at.kt (filename: V2__update_created_at.kt)
2024-05-12T00:16:23.754+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.scanner.Scanner        : Filtering out resource: db/migration/kotlin/V1__create_users_table.kt (filename: V1__create_users_table.kt)
2024-05-12T00:16:23.761+05:45  INFO 77861 --- [flyway-java-migration] [           main] o.f.core.internal.command.DbValidate     : Successfully validated 0 migrations (execution time 00:00.008s)
2024-05-12T00:16:23.761+05:45  WARN 77861 --- [flyway-java-migration] [           main] o.f.core.internal.command.DbValidate     : No migrations found. Are your locations set up correctly?
2024-05-12T00:16:23.762+05:45 DEBUG 77861 --- [flyway-java-migration] [           main] o.f.core.internal.command.DbSchemas      : Skipping creation of existing schema: "public"

It seems that it skipped the Java-based migrations.

Here is what my application.yml file looks like:

spring:
  application:
    name: flyway-java-migration
  flyway:
    locations: classpath:db/migration/kotlin

server:
  port: 8080
  shutdown: graceful

logging:
  level:
    org:
      flywaydb: DEBUG

Solution

  • This article posted by @BasilBourque helped me solve my problem. I had to do the following things to solve my problem:

    1. Move the files from src/main/resources/db/migration/kotlin to src/main/kotlin/db/migration so that Spring compliles the Kotlin files. The earlier Dzone article explains that files inside src/main/resources are not compiled, which is why you need to place the Java-based migration directly inside src/main.
    2. Remove the following lines from application.yml as we no longer place the Java-based migrations there:
      flyway:
        locations: classpath:db/migration/kotlin
    

    With just those changes, everything worked. I hope this answer is useful to others too as it was very hard for me to find a solution in the internet.