Drop Schema and recreate state with MultiTenantSpringLiquibase

Hi all,

Environment:

  • Spring Boot
    • SpringLiquibase Bean
    • MultitenantSpringLiquibase Bean
    • PostgreSql

I have an issue with dropping and recreating a schema with the same schema name and the way Liquibase handles its state. Is there support for the “dropAll(schema)” functionality associated with the SpringLiquibase integration so I can delete all tracking of a specific schema on request?

From the logs, I also noticed that SEARCH_PATH only adds schema names and never removes them.

The result of recreating the schemas is a databasechangelog/changeloglock table with none of the changesets applied or associated with it.

Configuration of beans:

@Bean
public SpringLiquibase liquibase(@Qualifier("taskExecutor") TaskExecutor taskExecutor,
                                 DataSource dataSource, LiquibaseProperties liquibaseProperties) {
    SpringLiquibase liquibase = new AsyncSpringLiquibase(taskExecutor, env);
    liquibase.setDataSource(dataSource);
    liquibase.setChangeLog("classpath:config/liquibase/liquibase-changelog.xml");
    liquibase.setContexts(liquibaseProperties.getContexts());
    liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
    liquibase.setDropFirst(liquibaseProperties.isDropFirst());
    liquibase.setShouldRun(true);

    return liquibase;
}

@Bean
@DependsOn("liquibase")
public MultiTenantSpringLiquibase liquibaseMt(DataSource dataSource, LiquibaseProperties liquibaseProperties) {
    MultiTenantSpringLiquibase liquibase = new MultiTenantSpringLiquibase();

    List<String> schemas = getAllSchemas();
    schemas.remove("pg_stat_statements");
    schemas.remove("pg_catalog");
    schemas.remove("pg_toast");
    schemas.remove("INFORMATION_SCHEMA");
    schemas.remove("information_schema");

    liquibase.setDataSource(dataSource);
    liquibase.setChangeLog("classpath:config/liquibase/liquibase-changelog.xml");
    liquibase.setContexts(liquibaseProperties.getContexts());
    liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
    liquibase.setSchemas(schemas);
    liquibase.setDropFirst(liquibaseProperties.isDropFirst());
    liquibase.setShouldRun(true);
    return liquibase;
}

Dropping / creating the schema:

public void removeSchema(String schemaName) {
    List<String> schemas = multiTenantSpringLiquibase.getSchemas();
    schemas.remove(schemaName);
    multiTenantSpringLiquibase.setSchemas(schemas);

    try {
        multiTenantSpringLiquibase.afterPropertiesSet();
        schemaRepo.dropSchema(schemaName);
    } catch (Exception e) {
        LOGGER.error("Error removing schema {}", schemaName);
    }
}


public boolean createAndMigrateProject(String schemaName) {
    if (multiTenantSpringLiquibase.getSchemas().contains(schemaName)) {
        return false;
    }

    this.migrating.add(schemaName);
    schemaRepo.createSchema(schemaName);
    multiTenantSpringLiquibase.getSchemas().add(schemaName);

    try {
        multiTenantSpringLiquibase.afterPropertiesSet();
        return true;
    } catch (Exception e) {
        this.migrating.remove(schemaName);
        LOGGER.error("Error creating schema {}", schemaName);
        return false;
    }
}

Thanks in advance for the help

Hi @Liquibase,

Any insight on this? I would love to get this working.

Thanks