Null Pointer Exception when trying to acquire lock

I get the following error from time to time when migrationg a local postgresql database, but the error occurs much more frequently when connecting via a network to the postgres database running on a small embedded platform (e.g. raspberry pi).

 

I have tried both liquibase 3.1.1 and also 3.1.2-SNAPSHOT.

 

Caused by: liquibase.exception.LockException: java.lang.NullPointerException
        at liquibase.lockservice.StandardLockService.acquireLock(StandardLockService.java:209)         at liquibase.lockservice.StandardLockService.waitForLock(StandardLockService.java:148)         at liquibase.Liquibase.update(Liquibase.java:189) 

        at liquibase.Liquibase.update(Liquibase.java:181) 

        at com.vaisala.jx.database.DatabaseMigrator.migrate(DatabaseMigrator.java:100) 

        … 4 common frames omitted
Caused by: java.lang.NullPointerException: null
        at liquibase.sqlgenerator.core.CreateTableGenerator.generateSql(CreateTableGenerator.java:106) 

        at liquibase.sqlgenerator.core.CreateTableGenerator.generateSql(CreateTableGenerator.java:27) 

        at liquibase.sqlgenerator.SqlGeneratorChain.generateSql(SqlGeneratorChain.java:30) 

        at liquibase.sqlgenerator.SqlGeneratorFactory.generateSql(SqlGeneratorFactory.java:198) 

        at liquibase.sqlgenerator.core.CreateDatabaseChangeLogLockTableGenerator.generateSql(CreateDatabaseChangeLogLockTableGenerator.java:36) 

        at liquibase.sqlgenerator.core.CreateDatabaseChangeLogLockTableGenerator.generateSql(CreateDatabaseChangeLogLockTableGenerator.java:19) 

        at liquibase.sqlgenerator.SqlGeneratorChain.generateSql(SqlGeneratorChain.java:30) 

        at liquibase.sqlgenerator.SqlGeneratorFactory.generateSql(SqlGeneratorFactory.java:198) 

        at liquibase.executor.AbstractExecutor.applyVisitors(AbstractExecutor.java:22) 

        at liquibase.executor.jvm.JdbcExecutor.access$500(JdbcExecutor.java:35) 

        at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:284) 

        at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:54) 

        at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:106)

        at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:96) 

        at liquibase.lockservice.StandardLockService.init(StandardLockService.java:83) 

        at liquibase.lockservice.StandardLockService.acquireLock(StandardLockService.java:182) 

        … 8 common frames omitted

 

 

Interestingly, if I run the code in debug mode, stepping throught the problematic statemets, it seems to work fine, perhaps suggetsing a timing problem?

 

I added a couple of additional log comments around the problem area (CreateTableGenerator.java, lines ~62)

 

        System.out.println("map of statement types " + statement.getColumnTypes().toString());       
        while (columnIterator.hasNext()) {
            String column = columnIterator.next();
            DatabaseDataType columnType = statement.getColumnTypes().get(column).toDatabaseDataType(database);
            System.out.println("column " + column + " columnType " + columnType);

and got this output:

map of statement types {LOCKGRANTED=datetime, LOCKED=boolean, LOCKEDBY=varchar(255), ID=int}
column ID columnType INT
column LOCKED columnType null

… NPE …

 

i.e. the LOCKED columnType is boolean in the map, but null when converted to databaseDataType, which implies that under some circumstances the toDatabaseDataType method returns null:

 

    public DatabaseDataType toDatabaseDataType(Database database) {
        DatabaseDataType type = new DatabaseDataType(name.toUpperCase(), getParameters());
        type.addAdditionalInformation(additionalInformation);

        return type;
    }

note that this method doesn’t appear to use the database parameter.

 

Have to admit that at this point I am confused, especially as the code works as you would expect when single-stepping through in debug mode. Any help much appreciated :wink: