Database Migrations in Spring Boot With Flyway

Introduction

Flyway is the Apache v2 licensed open-source tool that makes database migrations easy. You can think of Flyway as version control for your database. It lets you evolve your database schema easily and reliably across all your instances.

Flyway updates a database from one version to the next using migrations. We can write migrations either in SQL with database-specific syntax or in Java for advanced database transformations.

Migrations can either be versioned or repeatable. The former has a unique version and is applied exactly once. The latter does not have a version. Instead, they are (re-)applied every time their checksum changes.

Within a single migration run, repeatable migrations are always applied last, after pending versioned migrations have been executed. Repeatable migrations are applied in order of their description. For a single migration, all statements are run within a single database transaction.

Installation

Add the Flyway dependency to your pom.xml or build.gradle if you’re using Gradle instead of Maven.

Maven:

Gradle:

Optionally, if you want to use Flyway with command line eg. mvn flyway:info or ./gradlew flywayInfo, add the following plugin as well.

Spring Boot will then automatically autowire Flyway with its DataSource and invoke it on startup. Adding plugin with Spring Boot is optional

Maven Plugin:

Gradle Plugin:

 

Creating the Application

Let’s use Spring Boot CLI to generate the application. Fire up your terminal and type the following command to generate the project.

Once the project is generated, import it into your favorite IDE. The directory structure of the application would look like this –

Configuring MySQL and Hibernate

First, create a new MySQL database named flyway_demo.

Then Open src/main/application.properties file and add the following properties to it –

Please change spring.datasource.username and spring.datasource.password as per your MySQL installation.

The property spring.jpa.hibernate.ddl-auto is important. It tries to validate the database schema according to the entities that you have created in the application and throws an error if the schema doesn’t match the entity specifications.

Creating a Domain Entity

Let’s create a simple Entity in our application so that we can create and test flyway migration for this entity.

First, Create a new package called domain inside com.example.flywaydemo package. Then, create the following User.java file inside com.example.flywaydemo.domain package –

Creating a Flyway Migration script

Flyway tries to read database migration scripts from classpath:db/migration folder by default.

All the migration scripts must follow a particular naming convention – V<VERSION_NUMBER>__<NAME>.sql. Checkout the Official Flyway documentation to learn more about naming conventions.

Let’s create our very first database migration script. First, Create the db/migration folder inside src/main/resources directory –

Now, create a new file named V1__init.sql inside src/main/resources/db/migration directory and add the following sql scripts –

Running the Application

When you run the application, flyway will automatically check the current database version and apply any pending migrations.

Run the app by typing the following command in terminal –

When running the app for the first time, you’ll see the following logs pertaining to Flyway, which says that it has migrated the schema to version 1 – init.

How does Flyway manage migrations?

Flyway creates a table called flyway_schema_history when it runs the migration for the first time and stores all the meta-data required for versioning the migrations in this table.

You can check the contents of flyway_schema_history table in your mysql database –

It stores the current migration’s version, script file name, and checksum among other details in the table.

When you run the app, Flyway first validates the already applied migration scripts by calculating their checksum and matching it with the checksum stored in the meta-data table.

So, If you change V1__init.sql after the migration is applied, Flyway will throw an error saying that the checksum doesn’t match.

Therefore, for doing any changes to the schema, you need to create another migration script file with a new version V2__<NAME>.sql and let Flyway apply that when you run the app.

Conclusion

That’s all folks! In this article, You learned how to integrate Flyway in a Spring Boot application for versioning database changes.

Thank you for reading. See you in the next blog post.

Comments