How can I avoid ResultSet is closed exception in Java?

前端 未结 10 1001
渐次进展
渐次进展 2020-11-28 09:51

As soon as my code gets to my while(rs.next()) loop it produces the ResultSet is closed exception. What causes this exception and how can I correct

相关标签:
10条回答
  • 2020-11-28 10:17

    make sure you have closed all your statments and resultsets before running rs.next. Finaly guarantees this

    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();
        }
    
    0 讨论(0)
  • 2020-11-28 10:22

    Sounds like you executed another statement in the same connection before traversing the result set from the first statement. If you're nesting the processing of two result sets from the same database, you're doing something wrong. The combination of those sets should be done on the database side.

    0 讨论(0)
  • 2020-11-28 10:25

    This could be caused by a number of reasons, including the driver you are using.

    a) Some drivers do not allow nested statements. Depending if your driver supports JDBC 3.0 you should check the third parameter when creating the Statement object. For instance, I had the same problem with the JayBird driver to Firebird, but the code worked fine with the postgres driver. Then I added the third parameter to the createStatement method call and set it to ResultSet.HOLD_CURSORS_OVER_COMMIT, and the code started working fine for Firebird too.

    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) There could be a bug in your code. Remember that you cannot reuse the Statement object, once you re-execute a query on the same statement object, all the opened resultsets associated with the statement are closed. Make sure you are not closing the statement.

    0 讨论(0)
  • 2020-11-28 10:26

    Check whether you have declared the method where this code is executing as static. If it is static there may be some other thread resetting the ResultSet.

    0 讨论(0)
  • 2020-11-28 10:32

    You may have closed either the Connection or Statement that made the ResultSet, which would lead to the ResultSet being closed as well.

    0 讨论(0)
  • 2020-11-28 10:34

    The exception states that your result is closed. You should examine your code and look for all location where you issue a ResultSet.close() call. Also look for Statement.close() and Connection.close(). For sure, one of them gets called before rs.next() is called.

    0 讨论(0)
提交回复
热议问题