Search code examples
javamysqljunitliquibasechangeset

Liquibase Change set appears to be empty when executing update command


Before I explain my issue, I must declare that I'm a novice in Liquibase.

I'm trying to run liquibase update method in my Test class. My code reads the changeset file, acquires lock, reads from changelog and releases lock, but does not execute the changeset itself. Here's my structure:

Test class:

public class LiquibaseTestDbUtil {

    private static final String LIQUIBASE_CHANGELOG_FILE = "liquibase/liquibase-changelog-test.xml";
    private static final String UNIT_NAME = "com.ihsinformatics.tbreach.api.test";
    // Get entity manager
    EntityManager entityManager = Persistence.createEntityManagerFactory(
            UNIT_NAME).createEntityManager();

    @Before
    public void setupDatabase() throws Exception {
        Connection connection = ((SessionFactoryImpl) entityManager.unwrap(
                Session.class).getSessionFactory()).getConnectionProvider()
                .getConnection();
        Database database = DatabaseFactory.getInstance()
                .findCorrectDatabaseImplementation(
                        new JdbcConnection(connection));
        // Get liquibase instance / execute update / drop
        URL file = ClassLoaderUtil.getResource(LIQUIBASE_CHANGELOG_FILE,
                LiquibaseTestDbUtil.class);
        DatabaseChangeLog dbChangeLog = new DatabaseChangeLog(file.getPath());
        Liquibase liquibase = new Liquibase(dbChangeLog,
                new ClassLoaderResourceAccessor(), database);
        liquibase.update(new Contexts("test"));
        // liquibase.dropAll();
    }

    @Test
    public void someTestCase() throws Exception {
    }
}

Change log file:

<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">

    <property name="schemaName" value="tbreach_api_test" dbms="mysql,oracle,postgresql" />

    <changeSet author="owais.hussain" context="test" id="20180216-1" runOnChange="true">
        <createTable tableName="data_log" schemaName="${schemaName}">
            <column autoIncrement="true" name="log_id" type="INT">
                <constraints primaryKey="true" />
            </column>
            <column name="log_type" type="CHAR(6)">
                <constraints nullable="false" />
            </column>
            <column name="entity_name" type="VARCHAR(45)">
                <constraints nullable="false" />
            </column>
            <column name="record" type="TEXT" />
            <column name="description" type="TEXT" />
            <column name="date_created" type="datetime(6)">
                <constraints nullable="false" />
            </column>
            <column name="created_by" type="INT" />
            <column name="created_at" type="INT" />
            <column name="uuid" type="CHAR(38)">
                <constraints nullable="false" unique="true" />
            </column>
        </createTable>
    </changeSet>

    <!-- Test Data -->
    <changeSet author="owais.hussain" id="2018-02-19" runOnChange="true">
        <sqlFile dbms="mysql" path="src/test/resources/test-data.sql" />
    </changeSet>

</databaseChangeLog>

My persistence.xml file is kept in src/test/resources/META-INF/ directory with the following details:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="com.ihsinformatics.tbreach.api.test" transaction-type="RESOURCE_LOCAL">
        <description>
            Persistence unit for the JPA tutorial of the Hibernate Getting Started Guide
        </description>
        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/tbreach_api_test" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="mypassword" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>

    </persistence-unit>

</persistence>

I have the following dependencies in my pom.xml

  • junit 4.10
  • liquibase-core 3.5.4
  • mysql-connector-java 5.1.45
  • Other dependencies like log4j

When I execute the LiquibaseTestDbUtil as Junit in Eclipse, I get the following log:

log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO 2/19/18 2:40 PM: liquibase: Successfully acquired change log lock
INFO 2/19/18 2:40 PM: liquibase: Reading from tbreach_api_test.DATABASECHANGELOG
INFO 2/19/18 2:40 PM: liquibase: Successfully released change log lock

But my Database (tbreach_api_test) looks empty, with only 2 liquibase tables, in which the databasechangelog is empty.

I dived into Debug mode to see that the changeLog object in Liquibase class is initialized, but is empty.

What am I missing?

  • Note that I have commented out the liquibase.dropAll() method, so the DB changes should persist (as I know).

Solution

  • Try using alternative liquibase constructor

    Liquibase liquibase = new Liquibase(
        "your file path", 
        new FileSystemResourceAccessor(), 
        database
    );