javaspringliquibase

Use other spring beans in liquibase CustomTaskChange class


I need to do some data migration, which is too complex to do it in a liquibase changeset. We use spring

That's why I wrote a class implementing the liquibase.change.custom.CustomTaskChange class. I then reference it from within a changeset.

All is fine to this point.

My question is: Is it possible to get access to the other spring beans from within such a class?

When I try to use an autowired bean in this class, it's null, which makes me think that the autowiring is simply not done at this point?

I've also read in some other thread, that the Liquibase bean must be initialized before all other beans, is that correct?

Here is a snippet of the class I wrote:

@Component
public class UpdateJob2 implements CustomTaskChange {

private String param1;

@Autowired
private SomeBean someBean;

@Override
public void execute(Database database) throws CustomChangeException {
    try {
        List<SomeObject> titleTypes = someBean.getSomeObjects(
                param1
        );
    } catch (Exception e) {         
        throw new CustomChangeException();
    }
...

I get an exception and when debugging I can see that someBean is null.

Here is the config for the SpringLiquibase:

@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@ComponentScan({
"xxx.xxx.."})
public class DatabaseConfiguration {

@Bean
public SpringLiquibase springLiquibase() {
    SpringLiquibase liquibase = new SpringLiquibase();
    liquibase.setDataSource(dataSource());
    liquibase.setChangeLog("classpath:liquibase-changelog.xml");
    return liquibase;
}
...

Some more config:

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
     http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">

    <includeAll path="dbschema"/>

</databaseChangeLog>

And here the call from the changeset:

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
     http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">

<changeSet id="201509281536" author="sr">
        <customChange class="xxx.xxx.xxx.UpdateJob2">
            <param name="param1" value="2" />
        </customChange>
</changeSet>


Solution

  • The classes referenced in your changeset.xml are not managed by Spring, so the cool stuff like DI will not work.

    What you can do is to inject Spring beans into Non-Spring objects. See this answer: https://stackoverflow.com/a/1377740/4365460