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
This article posted by @BasilBourque helped me solve my problem. I had to do the following things to solve my problem:
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
.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.