org.h2.jdbc.JdbcSQLException: объект уже закрыт - PullRequest
0 голосов
/ 03 мая 2018

За свою жизнь я не вижу, как она "уже закрыта"

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();    
    }
}

вот вывод:

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)

, где 22 соответствует строке "while (rset.next ()) {"

БД возвращает значения, смотрите оператор println, который дает нам 103.

и даже страннее, если я // закомментирую строку executeUpdate, все завершится нормально

1 Ответ

0 голосов
/ 03 мая 2018

Исключение в потоке "main" org.h2.jdbc.JdbcSQLException: объект уже закрыт [90007-196]

Ваша проблема в том, что вы повторно используете SQL Statement внутри цикла while. Как только вы вызовете метод qry.executeUpdate(...) в цикле, ResultSet rset, связанный с предыдущим оператором, закроется, что приведет к ошибке. Это оператор while(rset.next()), который называется после первого executeUpdate(...) в цикле, который завершается неудачей.

Если вы используете в цикле оператор new , он должен работать.

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 ...");
}

Возможно, вы захотите сохранить коллекцию необходимых обновлений, а затем выпустить обновления в конце цикла.

и еще более странно, если я // закомментирую строку executeUpdate, все завершится нормально

Да, это звучит правильно. Совсем не странно. : -)

...