使用PreparedStatement时IndexOutOfBounds

时间:2018-03-16 15:10:47

标签: java jdbc transactions prepared-statement

当我尝试将多个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

2 个答案:

答案 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)

Javadoc

/**
 * 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