1. Introduction
In this article, which is a continuation of a Flyway series we will learn how to add Flyway to an existing Spring Boot Project.
If you are not sure what this tool can bring to your project, then check out my first post on Flyway with Spring Boot, where you can find all the necessary information.
2. Project Setup
This time, we won’t spend time preparing a sample project (well, if you are here then there’s a 95% chance that you already have some project).
Nevertheless, if you don’t have one, but still would like to learn how to add a flyway to an existing Spring Boot project, then no worries. You can find an example project in this GitHub repository.
Note: If you use the project from the linked repository, then please run the script.sql file (can be found in /resources/sql directory) against your database, before you start the application.
3. Strategy For Adding Flyway To Existing Spring Boot Project
Before we start anything, I just wanted to emphasize that we should always create a backup, before performing any operations on our databases. Regardless of how widely used, or well-tested the tool is, something can always go wrong and we have to be ready to roll out plan B.
3.1 Add Flyway Dependency
As the first thing (after the backup!), let’s add the necessary dependency to our Spring Boot project.
For gradle, it will look as follows:
implementation 'org.flywaydb:flyway-core:9.8.3'
On the other hand, when working with Maven, we need to add these lines:
<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>9.8.3</version> </dependency>
3.2 Verify Spring Boot App
Nextly, let’s run our Spring Boot application and verify, whether anything changed:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Found non-empty schema(s) "custom_schema" but no schema history table. Use baseline() or set baselineOnMigrate to true to initialize the schema history table. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1751) ~[spring-beans-6.0.2.jar:6.0.2]
As we can clearly see, Flyway throws a pretty descriptive message:
Found non-empty schema(s) “custom_schema” but no schema history table. Use baseline() or set baselineOnMigrate to true to initialize the schema history table.
And basically, this error clearly states what we need to do when adding a Flyway to an existing project. But before that, we have to take care of a couple of things.
3.3 Generate Production Database DDL
Firstly, we have to generate an SQL script containing the DDL our production database, including:
- procedures
- views,
- triggers etc…
I won’t go into details here, because DDL script generation depends on the database you are using. Nevertheless, it can be done pretty easily with tools like DataGrip, DBeaver, or pg_dump.
And when the SQL script with DDL is ready, let’s save it in the Flyway migrations directory (in Spring Boot the default one is resources/db/migration). Of course, we have to remember about the Flyway files naming convention, so the file name should be something, like V1__my_custom_init_script.sql.
3.4 Clear Irrelevant Data
If you have only one database instance in your project, then feel free to skip this point. Otherwise, we have to make sure that the generated DDL script will work in every other environment. And we can achieve it in two ways:
- if we don’t care about the data in other environments- then we can run the Flyway clean command.
- however, if we do actually care about the data in our non-production environments, then there’s no other choice than to manually verify and align other database structures with the main one.
The choice here is yours and will depend on many factors, like the importance of test data, amount of environments, etc.
Nevertheless, if you would like to clean your database before adding a Flyway to your existing project, then you can do that with the following:
flyway -defaultSchema="custom_schema" \ -url="jdbc:postgresql://{URL}:{PORT}/{DB_NAME}" \ -cleanDisabled="false" \ -user="{USERNAME}" \ clean
Please keep in mind that with this command, we will be prompted to enter the password manually (and alternatively, we can pass the -password flag).
3.5 Add Flyway To Existing Spring Boot Project
Finally, with all that being done, we can return to the Spring Boot project and make the necessary changes.
Let’s navigate to the application.yaml file and insert these settings:
spring: flyway: baselineOnMigrate: true defaultSchema: "custom_schema" # not necessary, but most likely you'll want to point to a specific schema
As we can see, with baselineOnMigrate set to true, we instruct Flyway to automatically call baseline when migration is executed against a non-empty schema. Additionally, we set the defaultSchema value, but this is totally optional.
As a result, the flyway_schema_history table is added to our schema:
and populated with precisely one record.
Please remember that the baselineOnMigrate set to true is only required once- when we do the initial deployment and can be removed after that.
3.6 Add Flyway Using Commands
Basically, with all of the above being done we are finished and can enjoy the benefits of Flyway in our project.
However, if you would like to learn how to add Flyway to an existing project using CLI, then you can do exactly the same with the following command:
flyway -defaultSchema="custom_schema" \ -url="jdbc:postgresql://{HOST}:{PORT}/{DB_NAME}" \ -user="USERNAME" \ -baselineOnMigrate="true" \ -locations="filesystem:." migrate
Or, alternatively, run baseline only:
flyway -defaultSchema="custom_schema" \ -url="jdbc:postgresql://{HOST}:{PORT}/{DB_NAME}" \ -user="USERNAME" \ -locations="filesystem:." baseline
And then the migrate command:
flyway -defaultSchema="custom_schema" \ -url="jdbc:postgresql://{HOST}:{PORT}/{DB_NAME}" \ -user="USERNAME" \ -locations="filesystem:." migrate
These commands might be useful if you would like to extract migrations to a separate directory (and/or repository).
4. Add Flyway To An Existing Spring Boot Project Summary
And that would be all in this article about how to add Flyway to an existing Spring Boot project. If you’d like to get to know Flyway better, then I highly encourage you to visit their documentation.
Let me know in the comments section in case of any questions 🙂