Java.DBMigrationTools.ManyDataSourcesExample

application.yml

spring:
  datasource:
    orders:
      url: jdbc:postgresql://localhost:5432/orders_db
      username: orders_user
      password: secret
      driver-class-name: org.postgresql.Driver
    billing:
      url: jdbc:postgresql://localhost:5432/billing_db
      username: billing_user
      password: secret
      driver-class-name: org.postgresql.Driver

  jpa:
    hibernate:
      ddl-auto: validate   # important: migrations own schema

  liquibase:
    enabled: false         # disable default single-datasource auto-config

DataSource + Liquibase beans (Java)

package com.example.config;

import javax.sql.DataSource;

import liquibase.integration.spring.SpringLiquibase;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MultiDbLiquibaseConfig {

    // ----------- DataSources -----------

    @Bean(name = "ordersDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.orders")
    public DataSource ordersDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "billingDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.billing")
    public DataSource billingDataSource() {
        return DataSourceBuilder.create().build();
    }

    // ----------- Liquibase per DB -----------

    @Bean
    public SpringLiquibase ordersLiquibase(@Qualifier("ordersDataSource") DataSource ds) {
        SpringLiquibase lb = new SpringLiquibase();
        lb.setDataSource(ds);
        lb.setChangeLog("classpath:db/changelog/orders/db.changelog-master.yaml");
        lb.setContexts("prod"); // optional
        lb.setShouldRun(true);
        return lb;
    }

    @Bean
    public SpringLiquibase billingLiquibase(@Qualifier("billingDataSource") DataSource ds) {
        SpringLiquibase lb = new SpringLiquibase();
        lb.setDataSource(ds);
        lb.setChangeLog("classpath:db/changelog/billing/db.changelog-master.yaml");
        lb.setContexts("prod"); // optional
        lb.setShouldRun(true);
        return lb;
    }
}

Folder structure example:

src/main/resources/db/changelog/orders/db.changelog-master.yaml
src/main/resources/db/changelog/billing/db.changelog-master.yaml

Why disable spring.liquibase.enabled?

Spring Boot’s default Liquibase auto-config assumes one datasource. With multiple DBs, you want explicit control so:

  • each changelog targets the right DB
  • failures are obvious
  • no accidental migrations against the wrong schema

Interview tip (what to say)

“In multi-datasource apps, I disable the default Liquibase auto-config and define one SpringLiquibase bean per datasource, each pointing to its own changelog. I also set Hibernate ddl-auto=validate so schema changes only come from migrations.”

This entry was posted in Без рубрики. Bookmark the permalink.