I have an external SpringBoot commons library (built as a jar
) and a main project that includes it.
The external library requires a set of default database tables. For this, I have set up Liquibase. The main project also makes us of Liquibase. Both projects have different changelog files. Suppose one is named library.xml
and the other main.xml
. All database and Liquibase properties are configured in the main project (as well as spring.liquibase.change-log=main.xml
).
The library has a single property: spring.liquibase.change-log=library.xml
.
How can I tell Liquibase "Run both library.xml
and main.xml
"? I suppose there is something I need to configure in the library project, since the main application should use it as is (simply by importing and using it).
To combine/structure our (liquibase) change logs, we can:
include
"attribute" (et al.).@Bean SpringLiquibase
s:
(main project) application.properties
:
spring.liquibase.change-log=classpath:/main.xml
# many more with same prefix ...
lib.liquibase.change-log=classpath:/library.xml
# according for lib.liquibase.* ...
Main/Config class:
@SpringBootApplication(/* scanBasePackages = "com.example.lib" */)
// We need/want these:
@EnableConfigurationProperties(LiquibaseProperties.class)
public class Demo {
@Bean // "main" liquibase:
// when order matters: @DependsOn("liquibaseLib")
@ConfigurationProperties("spring.liquibase") // !
public SpringLiquibase liquibase(
ObjectProvider<DataSource> dataSource,
@LiquibaseDataSource ObjectProvider<DataSource> liquibaseDataSource,
LiquibaseProperties properties) {
return liqui(dataSource, liquibaseDataSource, properties);
}
@Bean // lib liquibase:
@ConfigurationProperties("lib.liquibase")
public SpringLiquibase liquibaseLib(
ObjectProvider<DataSource> dataSource,
/* alternatively: @MyVeryCustomDataSource ... */
@LiquibaseDataSource ObjectProvider<DataSource> liquibaseDataSource,
LiquibaseProperties properties) {
return liqui(dataSource, liquibaseDataSource, properties);
}
// pstvm...
private SpringLiquibase liqui(ObjectProvider<DataSource> dataSource,
ObjectProvider<DataSource> liquibaseDataSource, LiquibaseProperties properties) {
// trick: Don't use LiquibaseConfiguration as `@Configuration/Bean`
// , it is not "repeatable" (in regards of liquibase execution;(
// , but rather as a "utility object"/factory:
LiquibaseConfiguration helpr = new LiquibaseConfiguration(properties);
return helpr.liquibase(dataSource, liquibaseDataSource);
}
}
Header (package+imports) of Demo.java:
package com.example.app;import javax.sql.DataSource; import liquibase.integration.spring.SpringLiquibase; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseConfiguration; import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource; import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.DependsOn;
...as shown by 2:
import liquibase.integration.spring.SpringLiquibase; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.DependsOn; import javax.sql.DataSource; @Configuration // scanned/imported/used by "main" ! public class MultipleLiquiaseConfiguration { @Bean public SpringLiquibase liquibaseLib(DataSource dataSource) { // ! SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog("classpath:library.xml"); // ! return liquibase; } @Bean // when order matters: @DependsOn("liquibaseLib") public SpringLiquibase liquibaseMain(DataSource dataSource) { // ! SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog("classpath:main.xml"); // ! return liquibase; } }
Regarding:
The library has a single property...
I hope it is a test property;)!