We have an data-migration job which needs to initialize schemas A
and B
, in that order. We handle multiple schemas by defining multiple SpringLiquibase
, one for each schema, each with its own datasource and its own master changeset. (Note, normally in Spring Boot you wouldn't need to define a SpringLiquibase, because it would detect a single datasource and auto-configure the SpringLiquibase for you with that datasource.)
The execution order seems to vary depending whether the job is run locally within the IDE, or bundled as a single-JAR Spring Boot app.
How can we ensure that the two executions of liquibase happen in the order we want?
(Why the order is important: A
contains some tables, while B
contains views that reference tables in A
. We have to make sure that we grant select on A.* to B
before attempting to create view B.some_view (...) as select ... from A.xyz
, otherwise the creation of B fails due to insufficient privileges.)
After some scratching of heads and digging into the source code, it turns out to be extremely simple.
SpringLiquibase implements InitializingBean
and executes the Liquibase update within the InitializingBean.afterPropertiesSet()
method.
Spring calls this method on each bean, one by one, after finishing initializing each one.
So to force a particular order, you need to force the order in which the beans are defined in the Spring context. And the easiest way to do this is with the @DependsOn
annotation.
So we put in place something like:
@Bean
public SpringLiquibase liquibaseA(
@Qualifier("dataSourceA") DataSource dataSource,
@Qualifier("liquibasePropertiesA") LiquibaseProperties liquibaseProperties
) {
return instantiateSpringLiquibase(dataSource, liquibaseProperties);
}
@Bean
@DependsOn("liquibaseA")
public SpringLiquibase liquibaseB(
@Qualifier("dataSourceB") DataSource dataSource,
@Qualifier("liquibasePropertiesB") LiquibaseProperties liquibaseProperties
) {
return instantiateSpringLiquibase(dataSource, liquibaseProperties);
}
private SpringLiquibase instantiateSpringLiquibase(DataSource dataSource, LiquibaseProperties liquibaseProperties) {
// set the datasource from dataSource and everything else from liquibaseProperties
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments