Search code examples
javaapache-cayenne

Apache Cayenne: NullPointerException when commitChanges


I'm trying commitChanges, but catch java.lang.NullPointerException. log:

...  
INFO: --- transaction started.
авг 04, 2015 12:33:59 PM org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy processSchemaUpdate
INFO: Full or partial schema detected, skipping tables creation
авг 04, 2015 12:33:59 PM org.apache.cayenne.log.CommonsJdbcEventLogger logQuery
INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = 'ARTIST'
авг 04, 2015 12:33:59 PM org.apache.cayenne.log.CommonsJdbcEventLogger logSelectCount
INFO: === returned 1 row. - took 16 ms.
авг 04, 2015 12:33:59 PM org.apache.cayenne.log.CommonsJdbcEventLogger logQueryError
INFO: *** error.
java.lang.NullPointerException
    at com.relx.jdbc.jdbc2.LinterStatementImpl.getUpdateCount(LinterStatementImpl.java:419)
    at org.apache.cayenne.access.jdbc.SQLTemplateAction.execute(SQLTemplateAction.java:190)
    at org.apache.cayenne.access.jdbc.SQLTemplateAction.performAction(SQLTemplateAction.java:124)
    at org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAction.java:87)
    at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:280)
    at org.apache.cayenne.dba.JdbcPkGenerator.longPkFromDatabase(JdbcPkGenerator.java:310)
    at org.apache.cayenne.dba.JdbcPkGenerator.generatePk(JdbcPkGenerator.java:268)
    at org.apache.cayenne.access.DataDomainInsertBucket.createPermIds(DataDomainInsertBucket.java:171)
    at org.apache.cayenne.access.DataDomainInsertBucket.appendQueriesInternal(DataDomainInsertBucket.java:76)
    at org.apache.cayenne.access.DataDomainSyncBucket.appendQueries(DataDomainSyncBucket.java:78)
    at org.apache.cayenne.access.DataDomainFlushAction.preprocess(DataDomainFlushAction.java:188)
    at org.apache.cayenne.access.DataDomainFlushAction.flush(DataDomainFlushAction.java:144)
    at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:853)
    at org.apache.cayenne.access.DataDomain$2.transform(DataDomain.java:817)
    at org.apache.cayenne.access.DataDomain.runInTransaction(DataDomain.java:877)
    at org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:814)
    at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:1031)
    at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:785)
    at org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:817)
    at org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:756)
    at CayenneTest2.main(CayenneTest2.java:61)

Table AUTO_PK_SUPPORT was created and filled Apache Cayenne. Why throw the Exception?


Solution

  • From the stack trace you are working with Cayenne v. 3.1. The code in question is here. Cayenne SQLTemplateAction checks whether the result of the query is a ResultSet and with the answer being "no", assumes the result is an update count. So it tries to read the update count on line 190:

     int updateCount = statement.getUpdateCount();
    

    Somehow the underlying statement object (LinterStatementImpl) is not happy about that. I don't have access to source code of the Linter DB driver, so I can't say what exactly is wrong, but the driver is not behaving the way Cayenne expects it to.

    Perhaps Linter is special enough to warrant its own Cayenne DbAdapter (??) Feel free to join Cayenne dev mailing list to discuss what it takes to write one.