The property spring.flyway.locations
sets the location of resources for Flyway migrations.
This is ignored for Fixed Java Migrations, when they come via FlywayAutoConfiguration
.
FlywayAutoConfiguration
sets all Spring Beans from the current Application Context into the Flyway Configuration regardless of the given Locations settings.
Release: 2.3.1.RELEASE
Example
There are two Java packages with Flyway Java Migration classes:
- db.migration1
- db.migration2
The former contains a Spring Component, the latter not.
Setting the property spring.flyway.locations
to classpath:db/migration1
will result to execution of only Migrations from the package db.migration1
- that's correct.
On the other hand, setting the property spring.flyway.locations
to classpath:db/migration1
will result to execution of only Migrations from both packages db.migration1
and db.migration2
as well - that's incorrect.
Demo Code
https://github.com/ttulka/spring-boot-samples/tree/master/flyway-fixed-java-migrations-bug
Comment From: wilkinsona
Thanks for the report and sample.
As noted in the documentation, " Flyway will be auto-configured with any beans that implement JavaMigration". You have component-scanned both db/migration1
and db/migration2
. The db.migration1
package contains V1_0__test_spring_bean
which is a @Component
so it becomes a bean in the application context and it is registered with Flyway. spring.flyway.location
configures Flyway's own migration discovery and has no effect on component scanning and the registration of components as beans in the context. In short, this is working as intended and as described in the documentation.
You haven't described your use case, but if you would like finer control over the migrations that Flyway uses, you should do that by controlling whether or not V1_0__test_spring_bean
is registered in the context. One way to achieve that is by using profiles and @Profile
to include or exclude V1_0__test_spring_bean
from the context's beans as required.
Comment From: ttulka
Many thanks for the reply!
this is working as intended and as described in the documentation
Is there any intention to improve it?
My use-case:
I have multiple schemas to be migrated in a particular order, one by one.
To achieve that I'm using my own implementation of FlywayMigrationStrategy
. This will create new FlywayConfig
and Flyway
instances per schema and call the method migrate()
upon them. Every instance has a single different schema and location per schema, eg. classpath:db/migration/schema1
for schema1
, classpath:db/migration/schema2
for schema2
etc.
Everything works fine except the migrations which are registered as Beans in Spring Context (because they need access to another beans). Those migrations are executed multiple times, exactly once per every migrate()
call regardless the configuration (location setting).
To control if the bean is registered or not doesn't seem to be applicable. Is there any other way in the current Spring Boot?
Comment From: ttulka
One way would be to filter the Java Migration in the config, similar as follows:
flywayConfig.javaMigrations(Arrays.stream(flywayConfig.getJavaMigrations())
.filter(jm -> jm.getClass().getPackageName().endsWith(schema))
.toArray(JavaMigration[]::new));
It's unfortunatelly pretty hacky :)
Comment From: wilkinsona
To achieve that I'm using my own implementation of
FlywayMigrationStrategy
. This will create newFlywayConfig
andFlyway
instances per schema and call the methodmigrate()
upon them.
The FlywayMigrationStrategy
is intended to control how the auto-configured Flyway
instance is migrated. It's not really being used as intended if you are creating new Flyway
instances when it is called.
As you are creating your own Flyway
instances already, I suspect that the auto-configuration isn't providing much value. It is aimed at the typical situation where there's a single DataSource
that needs to be migrated with that migration being handled by a single Flyway
instance. If you need to work with multiple Flyway
instances to satisfy your ordering requirements, I would exclude FlywayAutoConfiguration
or define your own Flyway
bean (that will cause the auto-configuration to back off) and do everything yourself.
Comment From: ttulka
Thanks, I'm happy with this :-)