Derby INSERT SELECT исключение нулевого указателя - PullRequest
2 голосов
/ 17 августа 2010

Я пишу Java-приложение, которое работает с Apache Derby через JDBC. У меня проблемы с кодом в следующем фрагменте:

byte md5[] = md5sum(file);

PreparedStatement s = con.prepareStatement("INSERT INTO input_files (job_ID, hash) SELECT job_id, ? FROM job WHERE job_name = ?");
s.setBytes(1, md5);
s.setString(2, jobName);
s.executeUpdate();
s.close();

Это вставляет в следующие таблицы:

CREATE TABLE input_files
(
    hash char(16) for bit data,
    job_id integer REFERENCES job,
    PRIMARY KEY(job_id, hash)
);

CREATE TABLE job
(
    job_id integer PRIMARY KEY GENERATED ALWAYS as IDENTITY,
    job_name character varying(50) UNIQUE NOT NULL,
    #other fields
);

Идея состоит в том, что существует внутреннее целое число job_id, которое используется базой данных для внутреннего использования, но мы хотим как можно больше ссылаться на него с помощью читаемой человеком строки job_name

Это последовательно вызывает следующее исключение.

java.sql.SQLException: Java exception: ': java.lang.NullPointerException'.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.javaException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(UnknownSource)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
    at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at [line 3 of snippet above]

Как вы можете видеть, это выбрасывается из строки, где создается подготовленный оператор - это не так далеко, как его выполнение. Что я делаю неправильно? Точно такой же подготовленный оператор отлично работает с PostgreSQL.

[править] Derby.log:

----------------------------------------------------------------
2010-08-18 08:47:08.779 GMT:
 Booting Derby version The Apache Software Foundation - Apache Derby - 10.6.1.0 - (938214): instance a816c00e-012a-8461-611c-0000046700d0 
on database directory /path/to/myDatabase   with class loader sun.misc.Launcher$AppClassLoader@6d6f0472

Database Class Loader started - derby.database.classpath=''
2010-08-18 08:47:12.067 GMT Thread[SwingWorker-pool-1-thread-1,5,main] (XID = 316), (SESSIONID = 1), (DATABASE = myDatabase), (DRDAID = null), Cleanup action starting
2010-08-18 08:47:12.067 GMT Thread[SwingWorker-pool-1-thread-1,5,main] (XID = 316), (SESSIONID = 1), (DATABASE = myDatabase), (DRDAID = null), Failed Statement is: INSERT INTO input_files (job_id, hash) SELECT job_id, ? FROM job WHERE job_name = ?
java.lang.NullPointerException
    at org.apache.derby.impl.sql.compile.BitTypeCompiler.storable(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumn.checkStorableExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumn.checkStorableExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumnList.checkStorableExpressions(Unknown Source)
    at org.apache.derby.impl.sql.compile.InsertNode.bindStatement(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
    at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
    at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at [line 3 of snippet]
Cleanup action completed

2010-08-18 08:47:12.084 GMT:
Shutting down instance a816c00e-012a-8461-611c-0000046700d0 with class loader sun.misc.Launcher$AppClassLoader@6d6f0472 
----------------------------------------------------------------

и развернутое исключение:

java.sql.SQLException: Java exception: ': java.lang.NullPointerException'.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.javaException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
    at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at [line 3 of snippet above]
Caused by: java.sql.SQLException: Java exception: ': java.lang.NullPointerException'.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
... 26 more
Caused by: java.lang.NullPointerException
    at org.apache.derby.impl.sql.compile.BitTypeCompiler.storable(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumn.checkStorableExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumn.checkStorableExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumnList.checkStorableExpressions(Unknown Source)
    at org.apache.derby.impl.sql.compile.InsertNode.bindStatement(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
    at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
... 19 more
SQLState: XJ001
Error code: 0
Message: Java exception: ': java.lang.NullPointerException'.
Cause: java.sql.SQLException: Java exception: ': java.lang.NullPointerException'.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.javaException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
    at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at [line 3 of snippet above]
Caused by: java.lang.NullPointerException
    at org.apache.derby.impl.sql.compile.BitTypeCompiler.storable(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumn.checkStorableExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumn.checkStorableExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumnList.checkStorableExpressions(Unknown Source)
    at org.apache.derby.impl.sql.compile.InsertNode.bindStatement(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
    at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
... 19 more
Cause:  java.lang.NullPointerException
    at org.apache.derby.impl.sql.compile.BitTypeCompiler.storable(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumn.checkStorableExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumn.checkStorableExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.ResultColumnList.checkStorableExpressions(Unknown Source)
    at org.apache.derby.impl.sql.compile.InsertNode.bindStatement(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
    at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement40.<init>(Unknown Source)
    at org.apache.derby.jdbc.Driver40.newEmbedPreparedStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
    at [line 3 of snippet above]

Ответы [ 3 ]

2 голосов
/ 17 августа 2010

Исключение нулевого указателя в этом контексте - особенно если тот же код JDBC работает с другой СУБД - похоже, что вы столкнулись с ошибкой в ​​драйвере Derby JDBC.Даже если вы допустили ошибку и передали ошибочные данные или нулевой указатель, драйвер должен обнаружить это и сообщить об ошибке, а не сбой.

1 голос
/ 17 августа 2010

Я подозреваю, что вы не сможете вставить буквальный хэш-код непосредственно в список столбцов выбора, потому что Дерби не понимает, что вы хотите поместить туда буквальное значение, а не имя столбца.

Разумный обходной путь может заключаться в том, чтобы перекодировать ваше приложение для выполнения оператора INSERT из цикла, который считывает значения из SELECT.Что-то вроде:

updateStatement = prepareStatement("insert into input_files (job_id, hash) values (?,?)")
ResultSet rs = executeQuery("select job_id from job where job_name = ?")
while (rs.next())
   updateStatement.setString(1, rs.getString(1))
   updateStatement.setBytes(2, md5sum)
   updateStatement.executeUpdate()
0 голосов
/ 17 августа 2010
 PreparedStatement s = con.prepareStatement("INSERT INTO input_files (job_ID, hash) SELECT job_id, ? FROM job WHERE job_name = ?");

"job_ID" против "job_id" совпадают с регистром и посмотрите, исправит ли это проблему.

...