Situation
I have a modular Spring Boot
project. As a database schema manager, I would like to use Flyway
.
As already stated, the project is modular. This is, because there will be different configurations which use different modules. This means, that I would like to pack everything that is related to a module to it's specific project. With Flyway
this seems not that simple.
Issue
What I ideally imagine:
ApplicationA
|
|_Module1
| |
| |_db/migration
| |
| |_V1__InitModule1Tables
| |_V2__MigrateSomeTable
|
|_Module2
|
|_db/migration
|
|_V1__InitModule2Tables
|_V2__MigrateSomeTable
Each module defines its own flyaway script independently, as they don't know from each others existence anyway. Each module would obviously need his own flyway history table inside of the share db. This way the whole system is decoupled and configuring the next application ApplicationB
with Module1
and Module3
won't be a hassle.
Well I didn't find any configuration possibility for Flyway
to reach this solution.
What I've tried
Doing something like this within each module is obviously a bad idea, as the the initialization/execution order of beans is rather random, leading in not having the tables created when I need them for other configurations. Also it seems messy.
@Configuration
public class Module1Config {
@Autowired
public void flyway(DataSource dataSource) {
Flyway flyway = new Flyway();
flyway.setBaselineOnMigrate(true);
flyway.setTable(flyway.getTable() + "-module1");
flyway.setDataSource(dataSource);
flyway.migrate();
}
}
I don't think that I'm the first person which tries to achieve that. How could I reach the desired modular Flyway
configuration?
* Update *
Solution
The following solution, which works in the way as the duplicate topic suggests, is working for me:
I crated a configuration template in my base
module which is used by any other module as it provides global functions as logging and journaling.
public abstract class FlywayConfig {
private final String moduleName;
public FlywayConfig(String moduleName) {
this.moduleName = moduleName;
}
private final String baseScriptLocation = "classpath:db.migration.";
@Autowired
public void migrate(DataSource dataSource) {
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
flyway.setSchemas(moduleName.toUpperCase());
flyway.setLocations(baseScriptLocation + moduleName.toLowerCase());
flyway.migrate();
}
}
In each module, I simply extend this configuration class
@Configuration
public class BaseConfig extends FlywayConfig {
public static final String MODULE_NAME = "base";
public BaseConfig() {
super(MODULE_NAME);
}
}
Whereas I save my flyway scripts in db.migration.*MODULE_NAME*