title: ResultSet closed error, when ResultSet or statement has not been closed
body: <p>I'm using the tomcat jdbc pool library for MySQL. Very rarely, a user will report seeing the following error:</p>
  
  <p><code>Operation not allowed after ResultSet closed</code></p>
  
  <p>The error points to the <code>while(rs.next())</code> code below, but I can't understand how it's being closed in the first place. The only place I close the resultset, the statement, or the connection is in the <code>finally</code> block, which leads me to believe that something in jdbc is automatically closing the resultset/statement if there's an error of some kind.</p>
  
  <p>I've seen similar issues across our app - a connection or statement being closed in the middle of the while loop, like during a batch insert or something.</p>
  
  <p>However, I can find no documentation about this. Here's our code, with unrelated portions removed but explained:</p>
  
  <pre><code>Connection conn = null;
  PreparedStatement s = null;
  ResultSet rs = null;
  try {
  
    conn = getConnection();
  
    if( conn == null || conn.isClosed() ){
      // ... we do stuff here 
    }
  
    s = conn.prepareStatement(query);
    rs = s.executeQuery();
  
    while(rs.next()){ // sometimes, we see "resultset closed" errors here, but we never close them
  
      try {
  
        // we read the data, construct an object with, i.e. rs.getString(3)
        // some is json we parse, so we catch exceptions
  
      } catch (Exception e) {
        if( !rs.isClosed() ){
          // print the primary key to help find the invalid record
        }
        e.printStackTrace();
      }
    }
  } catch (SQLException e) {
    handleDatabaseException( e );
  } finally {
    if(rs != null) try { rs.close(); } catch (SQLException ignored) {}
    if(s != null) try { s.close(); } catch (SQLException ignored) {}
    if(conn != null) try { conn.close(); } catch (SQLException ignored) {}
  }
  </code></pre>