Подтвердить что ты не робот

Как я могу избежать ResultSet является закрытым исключением в Java?

Как только мой код попадает в мой цикл while(rs.next()), он выдает исключение ResultSet. Что вызывает это исключение и как я могу его исправить?

EDIT: Я заметил в своем коде, что я вложен цикл while(rs.next()) с другим (rs2.next()), оба набора результатов, исходящие из одного и того же БД, это проблема?

4b9b3361

Ответ 1

Похоже, что вы выполнили другой оператор в том же соединении, прежде чем пересечь результирующий набор из первого оператора. Если вы размещаете обработку двух наборов результатов из одной базы данных, вы делаете что-то неправильно. Комбинация этих наборов должна выполняться на стороне базы данных.

Ответ 2

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

a) Некоторые драйверы не допускают вложенных операторов. В зависимости от того, поддерживает ли ваш драйвер JDBC 3.0, вы должны проверить третий параметр при создании объекта Statement. Например, у меня была такая же проблема с драйвером JayBird для Firebird, но код работал нормально с драйвером postgres. Затем я добавил третий параметр к вызову метода createStatement и установил его в ResultSet.HOLD_CURSORS_OVER_COMMIT, и код начал нормально работать и для Firebird.

static void testNestedRS() throws SQLException {

    Connection con =null;
    try {
        // GET A CONNECTION
        con = ConexionDesdeArchivo.obtenerConexion("examen-dest");
        String sql1 = "select * from reportes_clasificacion";

        Statement st1 = con.createStatement(
                ResultSet.TYPE_SCROLL_INSENSITIVE,
                ResultSet.CONCUR_READ_ONLY, 
                ResultSet.HOLD_CURSORS_OVER_COMMIT);
        ResultSet rs1 = null;

        try {
            // EXECUTE THE FIRST QRY
            rs1 = st1.executeQuery(sql1);

            while (rs1.next()) {
                // THIS LINE WILL BE PRINTED JUST ONCE ON
                                    // SOME DRIVERS UNLESS YOU CREATE THE STATEMENT 
                // WITH 3 PARAMETERS USING 
                                    // ResultSet.HOLD_CURSORS_OVER_COMMIT
                System.out.println("ST1 Row #: " + rs1.getRow());

                String sql2 = "select * from reportes";
                Statement st2 = con.createStatement(
                        ResultSet.TYPE_SCROLL_INSENSITIVE,
                        ResultSet.CONCUR_READ_ONLY);

                // EXECUTE THE SECOND QRY.  THIS CLOSES THE FIRST 
                // ResultSet ON SOME DRIVERS WITHOUT USING 
                                    // ResultSet.HOLD_CURSORS_OVER_COMMIT

                st2.executeQuery(sql2);

                st2.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            rs1.close();
            st1.close();
        }

    } catch (SQLException e) {

    } finally {
        con.close();

    }

}

b) В вашем коде может быть ошибка. Помните, что вы не можете повторно использовать объект Statement, как только вы повторно выполняете запрос в одном и том же объекте оператора, все открытые результирующие группы, связанные с оператором, будут закрыты. Убедитесь, что вы не закрываете оператор.

Ответ 3

Кроме того, у каждого оператора может быть только один результирующий набор. Поэтому, если вы повторяете два набора результатов одновременно, убедитесь, что они выполняются в разных операторах. Открытие второго результирующего набора в одном выражении косвенно закрывает первое. http://java.sun.com/javase/6/docs/api/java/sql/Statement.html

Ответ 4

Исключение указывает, что ваш результат закрыт. Вы должны изучить свой код и посмотреть все места, где вы вызываете вызов ResultSet.close(). Также найдите Statement.close() и Connection.close(). Конечно, один из них вызывается до того, как вызывается rs.next().

Ответ 5

Возможно, вы закрыли либо Connection, либо Statement, которые сделали ResultSet, что приведет к закрытию ResultSet.

Ответ 6

Правильный вызов jdbc должен выглядеть примерно так:

try { 
    Connection conn;
    Statement stmt;
    ResultSet rs; 

    try {
        conn = DriverManager.getConnection(myUrl,"",""); 
        stmt = conn.createStatement(); 
        rs = stmt.executeQuery(myQuery); 

        while ( rs.next() ) { 
            // process results
        } 

    } catch (SqlException e) { 
        System.err.println("Got an exception! "); 
        System.err.println(e.getMessage()); 
    } finally {
        // you should release your resources here
        if (rs != null) { 
            rs.close();
        }

        if (stmt != null) {
            stmt.close();
        }

        if (conn != null) {
            conn.close();
        }
    }
} catch (SqlException e) {
    System.err.println("Got an exception! "); 
    System.err.println(e.getMessage()); 
}

вы можете закрыть соединение (или оператор) только после получения результата из набора результатов. Самый безопасный способ - сделать это в блоке finally. Однако close() также мог бы задерживать SqlException, следовательно, другой блок try-catch.

Ответ 7

Проверьте, был ли вы объявлен метод, в котором этот код выполняется как static. Если это static, может быть какой-то другой поток, сбросив ResultSet.

Ответ 8

У меня такая же ошибка, все было правильно, только я использовал тот же объект интерфейса оператора для выполнения и обновления базы данных. После разделения, то есть с использованием разных объектов интерфейса оператора для обновления и выполнения запроса, я решил эту ошибку. то есть избавиться от этого, не используйте один и тот же объект-оператор для обновления и выполнения запроса.

Ответ 9

перед запуском rs.next убедитесь, что вы закрыли все свои статистические данные и наборы результатов. В конечном итоге это гарантирует

public boolean flowExists( Integer idStatusPrevious, Integer idStatus, Connection connection ) {
    LogUtil.logRequestMethod();

    PreparedStatement ps = null;
    ResultSet rs = null;
    try {
        ps = connection.prepareStatement( Constants.SCRIPT_SELECT_FIND_FLOW_STATUS_BY_STATUS );
        ps.setInt( 1, idStatusPrevious );
        ps.setInt( 2, idStatus );

        rs = ps.executeQuery();

        Long count = 0L;

        if ( rs != null ) {
            while ( rs.next() ) {
                count = rs.getLong( 1 );
                break;
            }
        }

        LogUtil.logSuccessMethod();

        return count > 0L;
    } catch ( Exception e ) {
        String errorMsg = String
            .format( Constants.ERROR_FINALIZED_METHOD, ( e.getMessage() != null ? e.getMessage() : "" ) );
        LogUtil.logError( errorMsg, e );

        throw new FatalException( errorMsg );
    } finally {
        rs.close();
        ps.close();
    }

Ответ 10

ResultSetClosedException может быть вызвано по двум причинам.

1.) Вы открыли другое соединение с базой данных, не закрывая все остальные соединения.

2.) Ваш ResultSet может не возвращать значения. Поэтому при попытке получить доступ к данным из ResultSet java сгенерирует ResultSetClosedException.