org.h2.jdbc.JdbcSQLException: The object is already closed

Opt*_*ier 2 java resultset h2

For the life of me I cannot see how it "is already closed"

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;


public class RsetTest2 {

    public static void main(String[] args) throws Exception {
        String dbpath = "jdbc:h2:c:/mydb;IFEXISTS=TRUE;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE";

        Connection conn = null;
        System.setProperty("h2.bindAddress", "127.0.0.1");
        Class.forName("org.h2.Driver");
        conn = DriverManager.getConnection(dbpath, "sa", "sa"); 
        conn.setAutoCommit(false);
        System.out.println("success.  querying database for latest values...");

        Statement qry = conn.createStatement();
        String sql = "select id from CONSTITUENTS where manager = 'abc' limit 1";                               
        ResultSet rset = qry.executeQuery(sql);
        while (rset.next()) {
            int id = rset.getInt("id");
            System.out.println(id);         
            qry.executeUpdate("insert into PAYREQUESTS (constituent, inblock) values (" + id + ", 238)");
        }
        rset.close();
        qry.close();    
    }
}
Run Code Online (Sandbox Code Playgroud)

here is the output:

success.  querying database for latest values...
103
Exception in thread "main" org.h2.jdbc.JdbcSQLException: The object is already closed [90007-196]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
    at org.h2.message.DbException.get(DbException.java:179)
    at org.h2.message.DbException.get(DbException.java:155)
    at org.h2.message.DbException.get(DbException.java:144)
    at org.h2.jdbc.JdbcResultSet.checkClosed(JdbcResultSet.java:3208)
    at org.h2.jdbc.JdbcResultSet.next(JdbcResultSet.java:130)
    at RsetTest2.main(RsetTest2.java:22)
Run Code Online (Sandbox Code Playgroud)

where 22 corresponds to the "while (rset.next()) {" line

the DB is returning values, see that println statement that gives us 103.

and even weirder, if I // comment out the executeUpdate line, it all completes normally

Gra*_*ray 6

线程“main”org.h2.jdbc.JdbcSQLException 中的异常:对象已经关闭 [90007-196]

您的问题是您Statementwhile循环内重用 SQL 。只要您qry.executeUpdate(...)在循环中调用该方法,ResultSet rset与前一个语句关联的 就会关闭,因此会出现错误。这是在循环中的第一个失败之后while(rset.next())调用的语句。executeUpdate(...)

如果您在循环中使用语句,那么它应该可以工作。

Statement qry = conn.createStatement();
String sql = "select id from CONSTITUENTS where manager = 'abc' limit 1";
ResultSet rset = qry.executeQuery(sql);
while (rset.next()) {
    int id = rset.getInt("id");
    System.out.println(id);
    // we can't reuse the same Statement here so we need to create a new one
    conn.createStatement().executeUpdate("insert into PAYREQUESTS ...");
}
Run Code Online (Sandbox Code Playgroud)

您可能会考虑保留一组必要的更新,然后在循环结束时发布更新。

更奇怪的是,如果我 // 注释掉 executeUpdate 行,它会正常完成

是的,听起来不错。一点都不奇怪。:-)