5
votes

I'm currently building a project for my internship, and I'm stuck since two days trying to use Liquibase in java. Everything seems right : the changelog file is found, correct URI, username and password; but when I run it, my changesets are not processed.

I use this class to manage liquibase actions from my program, such as rollback, update, updateSQL and futureRollbackSQL, given a changelog and eventually a destination file. If the source or destination is from a remote server, I use some SSH interactions (scp to, scp from) with JSch and temporary files (but it's not the topic).

This is the java code I have for now, given db, user, passwd, realAction are set previously, changelogpath and dest are some data storage class.

Connection c = null;
Database database = null;
PrintWriter pw = null;
File file = null;
liquibase.Liquibase liquibase = null;
contexts = db+"."+user;
try {
    pw = new PrintWriter(new FileWriter(file));
    // Get connection
    c = SQLManager.getInstance().getConnection(db, user, passwd);
    // Get liquibase connection
    database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(c));
    liquibase = new liquibase.Liquibase(new DatabaseChangeLog(fsource), new FileSystemResourceAccessor(),
            database);
    // Run liquibase action
    switch (realAction) {
        case Constants.LIQUIBASE_ACTION_FUTUREROLLBACKSQL:
            liquibase.futureRollbackSQL(pw);
            break;
        case Constants.LIQUIBASE_ACTION_UPDATESQL:
            liquibase.update(contexts, pw);
            break;
        case Constants.LIQUIBASE_ACTION_UPDATE:
            liquibase.update(contexts);
            if (!c.getAutoCommit())
                c.commit();
            break;
        default:
            throw new OdewipElementRuntimeException(this, "Action not implemented");
    }
    pw.close();
    database.close();
    c.close();
} catch (IOException | SQLException | LiquibaseException e) {
    throw new Exception(e.getMessage());
} finally {
    if (c != null) {
        try {
            c.close();
        } catch (SQLException e) {
            // nothing to do
            throw new RuntimeException(e.getClass() + ": " + e.getMessage());
        }
    }
}

And here is my changelog:

<?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"
  xmlns:ora="http://www.liquibase.org/xml/ns/dbchangelog-ext"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd    http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">    

    <changeSet id="mychangeset" author="testy">
        <preConditions onSqlOutput="TEST" onFail="MARK_RAN">
            <not>
                <tableExists tableName="abcd"/>
            </not>
        </preConditions>
        <createTable tableName="abcd">
            <column name="id" type="number">
                <constraints primaryKey="true"/>
            </column>
        </createTable>
    </changeSet>

</databaseChangeLog>

Liquibase seems to do something, except parsing my changeset. When I launch my actions, sql generated files only contains the creation of the two tables of liquibase (databasechangelog and databasechangeloglock) and that's all. The update action won't modify anything at all (not even creating the two previously mentioned tables). I'm (100%) sure that the table abcd does not exist in the database before execution.

So I think I need some help at this point, to figure out what isn't working. I tried to look at some examples from the liquibase forum, but nothing helped. I'm currently using Maven's liquibase 3.4.0:

<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
    <version>3.4.0</version>
</dependency>

Is there another dependency to include I missed? One small other question is how do I include a special oracle database driver(ojdbc6.jar)?

Thank you for your answers.

EDIT 06/08/2015: I got the logs in debug mode (deliberately changed the schema name):

DEBUG 06/08/15 09:28: liquibase: Executing QUERY database command: select count(*) from MYSCHEMA.DATABASECHANGELOGLOCK
DEBUG 06/08/15 09:28: liquibase: Create Database Lock Table
DEBUG 06/08/15 09:28: liquibase: Executing EXECUTE database command: CREATE TABLE MYSCHEMA.DATABASECHANGELOGLOCK (ID NUMBER(10) NOT NULL, LOCKED NUMBER(1) NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR2(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID))
DEBUG 06/08/15 09:28: liquibase: Created database lock table with name: MYSCHEMA.DATABASECHANGELOGLOCK
DEBUG 06/08/15 09:28: liquibase: Executing QUERY database command: select count(*) from MYSCHEMA.DATABASECHANGELOGLOCK
DEBUG 06/08/15 09:28: liquibase: Initialize Database Lock Table
DEBUG 06/08/15 09:28: liquibase: Executing EXECUTE database command: DELETE FROM MYSCHEMA.DATABASECHANGELOGLOCK
DEBUG 06/08/15 09:28: liquibase: Executing EXECUTE database command: INSERT INTO MYSCHEMA.DATABASECHANGELOGLOCK (ID, LOCKED) VALUES (1, 0)
DEBUG 06/08/15 09:28: liquibase: Executing QUERY database command: SELECT LOCKED FROM MYSCHEMA.DATABASECHANGELOGLOCK WHERE ID=1 FOR UPDATE
DEBUG 06/08/15 09:28: liquibase: Lock Database
DEBUG 06/08/15 09:28: liquibase: Executing UPDATE database command: UPDATE MYSCHEMA.DATABASECHANGELOGLOCK SET LOCKED = 1, LOCKEDBY = 'CRO09177 (xx.xx.xx.xxx)', LOCKGRANTED = to_date('2015-08-06 09:28:28', 'YYYY-MM-DD HH24:MI:SS') WHERE ID = 1 AND LOCKED = 0
INFO 06/08/15 09:28: liquibase: Successfully acquired change log lock
DEBUG 06/08/15 09:28: liquibase: Create Database Change Log Table
INFO 06/08/15 09:28: liquibase: Creating database history table with name: MYSCHEMA.DATABASECHANGELOG
DEBUG 06/08/15 09:28: liquibase: Executing EXECUTE database command: CREATE TABLE MYSCHEMA.DATABASECHANGELOG (ID VARCHAR2(255) NOT NULL, AUTHOR VARCHAR2(255) NOT NULL, FILENAME VARCHAR2(255) NOT NULL, DATEEXECUTED TIMESTAMP NOT NULL, ORDEREXECUTED NUMBER(10) NOT NULL, EXECTYPE VARCHAR2(10) NOT NULL, MD5SUM VARCHAR2(35), DESCRIPTION VARCHAR2(255), COMMENTS VARCHAR2(255), TAG VARCHAR2(255), LIQUIBASE VARCHAR2(20), CONTEXTS VARCHAR2(255), LABELS VARCHAR2(255))
DEBUG 06/08/15 09:28: liquibase: Executing QUERY database command: select count(*) from MYSCHEMA.DATABASECHANGELOG
INFO 06/08/15 09:28: liquibase: Reading from MYSCHEMA.DATABASECHANGELOG
DEBUG 06/08/15 09:28: liquibase: Executing QUERY database command: SELECT FILENAME,AUTHOR,ID,MD5SUM,DATEEXECUTED,ORDEREXECUTED,EXECTYPE,DESCRIPTION,COMMENTS,TAG,LIQUIBASE,LABELS,CONTEXTS FROM MYSCHEMA.DATABASECHANGELOG ORDER BY DATEEXECUTED ASC, ORDEREXECUTED ASC
DEBUG 06/08/15 09:28: liquibase: Executing QUERY database command: select count(*) from MYSCHEMA.DATABASECHANGELOGLOCK
DEBUG 06/08/15 09:28: liquibase: Release Database Lock
DEBUG 06/08/15 09:28: liquibase: Executing UPDATE database command: UPDATE MYSCHEMA.DATABASECHANGELOGLOCK SET LOCKED = 0, LOCKEDBY = NULL, LOCKGRANTED = NULL WHERE ID = 1
INFO 06/08/15 09:28: liquibase: Successfully released change log lock
2

2 Answers

2
votes

Here at Datical we have noticed that there are some issues with Liquibase and Java 1.8. You mentioned on your post to the Liquibase user forums that you were using Java 1.8, so it is possible that Java 1.8 may be the issue. Can you try using Java 1.7 and see if you get different results? If not, you could try increasing the logging level - add a line like this after you have created your Liquibase object:

LogFactory.getInstance().getLog().setLogLevel(logLevel);

Where logLevel is the string "debug"