当我尝试将多个PreparedStatements放入单个数据库事务时,有没有人知道为什么我得到一个ArrayIndexOutOfBounds -1?当我尝试在预准备语句中设置第一项时,它就会发生。这违背了我一直在阅读的所有内容,似乎无法弄明白。
PreparedStatement stmt = null;
Connection conn = null;
// Fetch the query and the request out of the QueryRequest object
conn = cpds.getConnection();
conn.setAutoCommit(false);
for (PrepStatementHolder a : query)
{
try
{
stmt = conn.prepareStatement("INSERT OR IGNORE INTO data(sampleTimestamp, data) values(?,?)");
stmt.setLong(0, a.getTimestamp());
stmt.setBytes(1, a.getBinaryData());
stmt.executeQuery();
} catch (Exception e)
{
e.printStackTrace();
errorLog.error("Query: " + a.getQuery() + " Timestamp " + a.getTimestamp() + " Data " + a.getBinaryData());
return false;
}
}
conn.commit();
stmt.close();
conn.close();
return true;
请求堆栈:
java.sql.SQLException: An SQLException was provoked by the following failure: ja
va.lang.ArrayIndexOutOfBoundsException: -1
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:118)
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:77)
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:74)
at com.mchange.v2.c3p0.impl.NewPooledConnection.handleThrowable(NewPoole
dConnection.java:505)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setLong(NewProxyPr
eparedStatement.java:184)
at com.joy.database.DBRunnable.dbCallInsert(DBRunnable.java:293)
at com.joy.database.DBRunnable.run(DBRunnable.java:129)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.
access$201(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.
run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
at org.sqlite.core.CorePreparedStatement.batch(CorePreparedStatement.jav
a:121)
at org.sqlite.jdbc3.JDBC3PreparedStatement.setLong(JDBC3PreparedStatemen
t.java:331)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setLong(NewProxyPr
eparedStatement.java:170)
... 9 more
答案 0 :(得分:1)
预准备语句的索引从1开始而不是0
stmt.setLong(0, a.getTimestamp());
stmt.setBytes(1, a.getBinaryData());
应该是
stmt.setLong(1, a.getTimestamp());
stmt.setBytes(2, a.getBinaryData());
答案 1 :(得分:1)
/** * Sets the designated parameter to the given Java <code>long</code> value. * The driver converts this * to an SQL <code>BIGINT</code> value when it sends it to the database. * * @param parameterIndex the first parameter is 1, the second is 2, ... * @param x the parameter value * @exception SQLException if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error occurs or * this method is called on a closed <code>PreparedStatement</code> */ void setLong(int parameterIndex, long x) throws SQLException;
第一个参数是 1