Database Migrations : Flyway for Spring Boot projects

aharmaz

Aymane Harmaz

Posted on June 6, 2024

Database Migrations : Flyway for Spring Boot projects

Like Liquibase, Flyway can be used in 2 main manners for database migrations in Spring Boot projects, either on application startup or in an independent way.

In this post we will see how to configure Flyway and use it in the context of a Spring Boot project for both development and release phases, You can find examples in the repository available at : Github Repository

Fundamental Concepts of Flyway

Migration and Migration Script :

A migration is the smallest coutable unit of change that Flyway can perform and register against a target database and it can involve one or more operations located on a file called migration script.

A migration in Flyway is equivalent to a changeset in Liquibase, however a migration script in Flyway is intended to host only a single migration, and a migration script in Liquibase can host multiple changesets

In Flyway executing a migration is equivalent to executing the migration script hosting that migration

flyway_schema_history Table :

This is the table Flyway creates on a database and uses for keeping track of what migrations has been already executed against that target database so that it does not run the same migration multiple times and it will be aware of what migrations it should run at a point of time (those that haven't been registered on the history table).

Each migration is identified by the filepath of the migration file where it is located. When Flyway runs a migration it calculate a checksum number for the content of that migration and stores it inside the flyway_schema_history table in order to make sure that the same migration won't be changed again

If Flyway notices that a changeset has been modified after it has been applied by comparing the checksums, it will throw an error during the migration process

Common Configuration

This consists of a folder on the resources directory of the project, then populate it with the migration files, in the example I have named it db/migrations :

  • V1_creating_persons_table.sql
  • V2_inserting_rows_into_persons_table.sql

Configuring Flyway to run migrations on application startup

This kind of behavior is commonly used at the development phase when a developer needs to update the state of the database he has on his local machine. Spring Boot offers some auto-configurations for launching the Flyway migration when the application is started.

For those auto-configuration to work we need to add some informations in the configuration file of the Spring Boot app related to local environments (application-local.yml) like the location of the database, the username and password of connection and the location of the migration files within the classpath of the application :

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/flyway_demo
    username: postgres
    password: changemeinproduction
    driver-class-name: org.postgresql.Driver
  jpa:
    hibernate:
      ddl-auto: none
  flyway:
    locations: classpath:db/migrations
Enter fullscreen mode Exit fullscreen mode

Then we should add flyway dependency in the pom.xml file of the project (build.gradle file if you are using Gradle) :

<dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Now when starting the application Spring Boot will notice the presence of the Flyway dependency on the classpath of the app and will uses the information in the configuration fi,le to trigger the auto-configuration that will be responsible for launching the migration process automcatically, here is an example of what you could see in the logs when the migration process is started :

2024-06-06T19:01:09.407+01:00  INFO 3229 --- [           main] org.flywaydb.core.FlywayExecutor         : Database: jdbc:postgresql://localhost:5432/flyway_demo (PostgreSQL 16.0)
2024-06-06T19:01:09.428+01:00  WARN 3229 --- [           main] o.f.c.internal.database.base.Database    : Flyway upgrade recommended: PostgreSQL 16.0 is newer than this version of Flyway and support has not been tested. The latest supported version of PostgreSQL is 15.
2024-06-06T19:01:09.450+01:00  INFO 3229 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Schema history table "public"."flyway_schema_history" does not exist yet
2024-06-06T19:01:09.453+01:00  INFO 3229 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 2 migrations (execution time 00:00.015s)
2024-06-06T19:01:09.486+01:00  INFO 3229 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table "public"."flyway_schema_history" ...
2024-06-06T19:01:09.538+01:00  INFO 3229 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema "public": << Empty Schema >>
2024-06-06T19:01:09.547+01:00  INFO 3229 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "public" to version "1 - creating persons table"
2024-06-06T19:01:09.606+01:00  INFO 3229 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "public" to version "2 - inserting rows into persons table"
2024-06-06T19:01:09.647+01:00  INFO 3229 --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 2 migrations to schema "public", now at version v2 (execution time 00:00.042s)
Enter fullscreen mode Exit fullscreen mode

Configuring Flyway to run migrations independently from running the application

This behavior is used when a new release of the software using a database is ready to be deployed, and a number of migrations must be applied on that database.

Maven provides a plugin for running Flyway migrations, this plugin will need to know about the database location, username and password of connection and the location of the migration files in the project folder, the way this can be configured is by adding a file on named flyway.conf to the resources folder of the Spring Boot project and then when adding the flyway maven plugin referencing the location of that file in the pom.xml :

flyway.user=postgres
flyway.password=changemeinproduction
flyway.schemas=demo_flyway
flyway.url=jdbc:postgresql://localhost:5432/demo_flyway
flyway.locations=src/main/resources/db/migrations
Enter fullscreen mode Exit fullscreen mode
<build>
  <plugins>
      <plugin>
         <groupId>org.flywaydb</groupId>
         <artifactId>flyway-maven-plugin</artifactId>
         <version>6.5.7</version>
         <configuration>
           <configFiles>
             <configFile>
               src/main/resources/flyway.conf
             </configFile>
           </configFiles>
         </configuration>
      </plugin>
  </plugins>
</build>
Enter fullscreen mode Exit fullscreen mode

If we want to launch the migration process using the Flyway maven plugin we must set the property spring.flyway.enabled to false so that when the application is started no migration is executed :

Finally we should run the migrations using the following command :

./mvnw flyway:migrate
Enter fullscreen mode Exit fullscreen mode

and we will be able to see the following logs indicating that the migrations has been executed succesfully.

[INFO] Scanning for projects...
[INFO] 
[INFO] ---------------------< ma.demo.flyway:flyway-demo >---------------------
[INFO] Building flyway-demo 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- flyway-maven-plugin:6.5.7:migrate (default-cli) @ flyway-demo ---
[INFO] Flyway Community Edition 6.5.7 by Redgate
[INFO] Database: jdbc:postgresql://localhost:5432/flyway_demo (PostgreSQL 16.0)
[WARNING] Flyway upgrade recommended: PostgreSQL 16.0 is newer than this version of Flyway and support has not been tested. The latest supported version of PostgreSQL is 12.
[INFO] Creating schema "flyway_demo" ...
[INFO] Creating Schema History table "flyway_demo"."flyway_schema_history" ...
[INFO] Current version of schema "flyway_demo": null
[INFO] Migrating schema "flyway_demo" to version 1 - creating persons table
[INFO] Migrating schema "flyway_demo" to version 2 - inserting rows into persons table
[INFO] Successfully applied 2 migrations to schema "flyway_demo" (execution time 00:00.066s)
[WARNING] Flyway upgrade recommended: PostgreSQL 16.0 is newer than this version of Flyway and support has not been tested. The latest supported version of PostgreSQL is 12.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.797 s
[INFO] Finished at: 2024-06-06T19:04:59+01:00
[INFO] ------------------------------------------------------------------------
Enter fullscreen mode Exit fullscreen mode

Conclusion
Flyway simplifies database migrations by ensuring that changes are applied consistently, in the context of Spring Boot, it can be integrated easily to launch the migration process at the startup of the application and this helps developer focus more on building new features without worrying about the state databases.

💖 💪 🙅 🚩
aharmaz
Aymane Harmaz

Posted on June 6, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related