I have two Spring profiles dev
and test
configured for development and test environment. And in each environment I am using different databases viz h2
in dev and postgresql
in testing. Following are my properties files for each profile where {vendor}
is resolved by spring boot to h2
and postgresql
repectively as per datasource configured.
application-dev.properties
spring.flyway.locations=classpath:db/migration/{vendor}
application-test.properties
#Data source
spring.datasource.url=jdbc:postgresql://localhost:5432/test
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
#Flyway
spring.flyway.check-location=false
spring.flyway.locations=classpath:/db/migration/test/{vendor}
Flyway migration files for dev
profile are under test/resources
and for test
profile under main/resources
This is working fine when I run my application with test
profile where it picks migration files only under main/resources
. However, When I run my unit test using dev
profile. I expect it to pick files only under src/test/resources/db/migration/h2
. But Flyway is picking up migration files from main/resources
and test/resources
both leading to error
org.flywaydb.core.api.FlywayException: Found more than one migration with version 1
I don't understand this behavior. Any inputs on how to fix this?
Flyway automatically discovers migrations on the filesystem and on the Java classpath.
Configuring Flyway Database gradle file. In application properties, we need to configure the database properties for creating a DataSource and also flyway properties we need to configure in application properties. For properties file users, add the below properties in the application. properties file.
Here are some thoughts about how to get database migration right. Flyway tries to enforce incremental database changes. That means we shouldn’t update already applied migrations, except repeatable ones. By default, we should use versioned migrations that will only be run once and will be skipped in subsequent migrations.
Spring Boot simplifies database migrations by providing integration with Flyway, one of the most widely used database migration tools. This guide presents various options of using Flyway as part of a Spring Boot application, as well as running it within a CI build. We’ll also cover the main advantages of having Database Migrations Done Right.
Flyway is a version control system that is used to maintain database migrations across all application instances. In this article, we will create a student management system that monitors database migrations using Flyway.
Flyway configurations You need to configure the Flyway-Maven plugin in the pom.xml as shown bellow: Flyway properties and scripts reside in the "src/main/resources" folder of the application. Here you can add as many configuration details as you need. "db/migration" - contains all the versions for every compilation.
So, here is how I did it.
Requirements:
dev
, test
and prod
.Database per environement:
H2
database for dev
environment.postgresql
database for test
environment.postgresql
database for prod
environment.Configuration
Create Spring profiles dev
, test
and prod
in pom.xml.
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
</profile>
<profile>
<id>prod</id>
</profile>
</profiles>
Create properties files for each profile
application-dev.properties
spring.flyway.locations=classpath:db/migration/{vendor}
Since, H2
database is configured by Spring boot when H2 driver is on classpath. We don't need to configure it explicitly.
application-test.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/db_test
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.flyway.locations=/db/{vendor}/common,/db/{vendor}/test
application-prod.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/db_prod
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.flyway.locations=/db/{vendor}/common,/db/{vendor}/prod
If you will notice, I have not used db/migration
under src/main/resources
to place migration files which is the default location. For simple reason that Flyway picks all the files under this location and which results in version conflict between files for different environments. For e.g V2__data_insertion.sql
is present for all three environments and this will not work if these were nested under db/migration
. Since, H2
migration files pertain to default profile I have left them at the default flyway migration file location.
Hope that helps !!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With