Liquibase Java validates changelogs but doesn't apply during update

I’ve been trying to create a tool to execute SQL queries using Liquibase’s Java library. I’m stuck on trying to apply the changelogs to the DB, even though the changelog files are found by liquibase, as evidenced by the validate() method executing correctly and logging each changelog file. Here’s a snippet of the method:

var databaseChangeLog = new DatabaseChangeLog("mychangelog.xml");
var resourceAccessor = new ClassLoaderResourceAccessor();
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(jdbcConnection);
var liquibase = new Liquibase(databaseChangeLog, resourceAccessor, database);

// This lists all changelogs and confirms they're valid.
liquibase.validate();

// This shows no changelogs to apply.
liquibase.update("");

The changelogs have not been executed prior to me trying to run this, the public.databasechangelog table is empty. Any ideas why it’s behaving like this?

When using the Liquibase class directly, you need to call the getDatabaseChangeLog() method to cause the changelog to be parsed. You can ignore the result of the call. The validate method does not parse the changelog.

String changeLogFile = "simple-changelog.xml";
var resourceAccessor = new ClassLoaderResourceAccessor();
var liquibase = new Liquibase(databaseChangeLog, resourceAccessor, database);
liquibase.getDatabaseChangeLog();
liquibase.validate();
liquibase.update("");

If you are using a more recent version of Liquibase, you can use the command framework, like this:

CommandScope updateCommand = new CommandScope(UpdateCommandStep.COMMAND_NAME);
updateCommand.addArgumentValue(DbUrlConnectionArgumentsCommandStep.DATABASE_ARG, database);
updateCommand.addArgumentValue(UpdateCommandStep.CHANGELOG_FILE_ARG, changeLogFile);
updateCommand.execute();

You don’t need to call getDatabaseChangeLog() or validate() with the command framework, as it gets called for you.