7

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 Flywayconfiguration?

* 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*

Herr Derb
  • 4,977
  • 5
  • 34
  • 62

1 Answers1

3

There are really only two possible scenarios here:

  1. Your modules are fully independent and there are no relationships in the database between objects belonging to different modules: use a separate schema history table per module.

  2. Your modules do have database objects with relationships to objects belonging to other modules: you now have in effect a single global lifecycle for the database and should therefore use a single schema history table for all modules.

More info about modular applications: https://speakerdeck.com/axelfontaine/majestic-modular-monoliths

Axel Fontaine
  • 34,542
  • 16
  • 106
  • 137
  • Yes, I really would like to go with approach 1 -> Completely independent. My problem is that I am really not sure how to configure Flyway to do so, as shown above. – Herr Derb Mar 19 '18 at 08:56
  • 1
    The approach you have outlined, along with the necessary @DependsOn annotations should be all you need. Alternatively put the objects for each module in their own schema. This is perfect use of your DB's built-in namespacing and that way no need to baselineOnMigrate and you can use the same table name. – Axel Fontaine Mar 19 '18 at 09:04