I need to set up liquibase for two datasources in Spring, at the moment it seems that only one liquibase set up is possib
I was in the need of supporting a dynamic amount of DataSources, not a fixed number of them. I found that you can use the same SpringLiquibase bean for multiple DataSources by making a service like this:
@Service
@DependsOn("liquibase")
public class LiquibaseService {
@Autowired
@Qualifier("liquibase")
private SpringLiquibase liquibase;
@PostConstruct
public void initialize() {
/* Obtain datasources from wherever. I obtain them from a master DB. It's up to you. */
List dataSources = obtainDataSources();
for (DataSource dataSource : dataSources) {
try {
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("classpath:liquibase/emp.changelog.xml");
liquibase.setShouldRun(true);
// This runs Liquibase
liquibase.afterPropertiesSet();
} catch (LiquibaseException ex) {
throw new RuntimeException(ex);
}
}
}
}
For this to work, you should have a SpringLiquibase bean declared somewhere. In this example, I got this in one of my configuration files:
@Bean
public SpringLiquibase liquibase(LiquibaseProperties properties) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(systemDataSource);
liquibase.setChangeLog("classpath:liquibase/sis.changelog.xml");
liquibase.setContexts(properties.getContexts());
liquibase.setDefaultSchema(properties.getDefaultSchema());
liquibase.setDropFirst(properties.isDropFirst());
liquibase.setLabels(properties.getLabels());
liquibase.setChangeLogParameters(properties.getParameters());
liquibase.setRollbackFile(properties.getRollbackFile());
// This is because we are running the process manually. Don't let SpringLiquibase do it.
liquibase.setShouldRun(false);
return liquibase;
}
The above highly depends on your DataSource configuration requirements. You could also need to put this on your main Application class so the Spring-Liquibase auto-configuration doesn't kick in:
@SpringBootApplication(exclude = {
LiquibaseAutoConfiguration.class
})
public class Application {
// Stuff...
}