Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle a modular spring project with flyway and single db [duplicate]

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*

like image 664
Herr Derb Avatar asked Mar 15 '18 15:03

Herr Derb


People also ask

What are some of the supported databases that Flyway is compatible with?

Supported databases are Oracle, SQL Server (including Amazon RDS and Azure SQL Database), Azure Synapse (Formerly Data Warehouse), DB2, MySQL (including Amazon RDS, Azure Database & Google Cloud SQL), Aurora MySQL, MariaDB, Percona XtraDB Cluster, TestContainers, PostgreSQL (including Amazon RDS, Azure Database, Google ...


1 Answers

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

like image 128
Axel Fontaine Avatar answered Sep 28 '22 23:09

Axel Fontaine