ResultSet not closed when connection closed?

65,970

Solution 1

One problem with ONLY closing the connection and not the result set, is that if your connection management code is using connection pooling, the connection.close() would just put the connection back in the pool. Additionally, some database have a cursor resource on the server that will not be freed properly unless it is explicitly closed.

Solution 2

I've had problems with unclosed ResultSets in Oracle, even though the connection was closed. The error I got was

"ORA-01000: maximum open cursors exceeded"

So: Always close your ResultSet!

Solution 3

You should always close all JDBC resources explicitly. As Aaron and John already said, closing a connection will often only return it to a pool and not all JDBC drivers are implemented exact the same way.

Here is a utility method that can be used from a finally block:

public static void closeEverything(ResultSet rs, Statement stmt,
        Connection con) {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) {
        }
    }
    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException e) {
        }
    }
    if (con != null) {
        try {
            con.close();
        } catch (SQLException e) {
        }
    }
}

Solution 4

Oracle will give you errors about open cursors in this case.

According to: http://java.sun.com/javase/6/docs/api/java/sql/Statement.html

it looks like reusing a statement will close any open resultsets, and closing a statement will close any resultsets, but i don't see anything about closing a connection will close any of the resources it created.

All of those details are left to the JDBC driver provider.

Its always safest to close everything explicitly. We wrote a util class that wraps everything with try{ xxx } catch (Throwable {} so that you can just call Utils.close(rs) and Utils.close(stmt), etc without having to worry about exceptions that close scan supposedly throw.

Solution 5

The ODBC Bridge can produce a memory leak with some ODBC drivers.

If you use a good JDBC driver then you should does not have any problems with closing the connection. But there are 2 problems:

  • Does you know if you have a good driver?
  • Will you use other JDBC drivers in the future?

That the best practice is to close it all.

Share:
65,970
jb.
Author by

jb.

Updated on October 08, 2020

Comments

  • jb.
    jb. over 3 years

    I've been doing code review (mostly using tools like FindBugs) of one of our pet projects and FindBugs marked following code as erroneous (pseudocode):

    Connection conn = dataSource.getConnection();
    
    try{
        PreparedStatement stmt = conn.prepareStatement();
        //initialize the statement
        stmt.execute();
        ResultSet rs =  stmt.getResultSet();
        //get data
    }finally{
        conn.close();
    }
    

    The error was that this code might not release resources. I figured out that the ResultSet and Statement were not closed, so I closed them in finally:

    finally{
        try{
            rs.close()
        }catch(SqlException se){
            //log it
        }
        try{
            stmt.close();
        }catch(SqlException se){
            //log it
        }
        conn.close();
    }
    

    But I encountered the above pattern in many projects (from quite a few companies), and no one was closing ResultSets or Statements.

    Did you have troubles with ResultSets and Statements not being closed when the Connection is closed?

    I found only this and it refers to Oracle having problems with closing ResultSets when closing Connections (we use Oracle db, hence my corrections). java.sql.api says nothing in Connection.close() javadoc.

  • jb.
    jb. over 15 years
    Its one point in this app. We use EJB, and this part was sort of plugin - our client would deploy a datasource on serwer, and then is able to query it through this plugin.
  • marcospereira
    marcospereira over 15 years
    The javadocs for Connection#close method says that "releases this Connection object's database and JDBC resources immediately". I think the problem is that some bad implementations don't do the right job. When pools don't close related resources, are they doing the wrong thing?
  • marcospereira
    marcospereira over 15 years
    Man, maybe we need a Closable interface, huh?
  • Ryan Fernandes
    Ryan Fernandes almost 15 years
    Most major vendor's JDBC drivers correspond to spec. However, most (if not all) application servers maintain a pool of connections. They wrap the native connection and reimplement methods like close() so that the connections can be 'pooled'. This means that if you work in these environments, you MUST close resources like Statements and ResultSets yourself.
  • Tim Büthe
    Tim Büthe over 13 years
    ResultSet are closed automatically when you close the Statement. (See JavaDoc download.oracle.com/javase/1.4.2/docs/api/java/sql/…)
  • Tim Büthe
    Tim Büthe over 13 years
    @Ryan Fernandes: Well, some pool just give you a connectionProxy object that saves all opened statements on it. When it gets returned in the pool, it closes all opened statements.
  • Abboq
    Abboq about 13 years
    Thanks for posting. I like this idea.
  • ggkmath
    ggkmath almost 12 years
    From this post's stackoverflow.com/questions/11160557/… response from Brunoss (see Miserable Variable comment), you may want to reverse the order of closing rs and stmt (close stmt before rs).
  • user454322
    user454322 over 11 years
    but i don't see anything about closing a connection will close any of the resources it created. docs.oracle.com/javase/6/docs/api/java/sql/… releases this Connection object's database and JDBC resources immediately But yeah, always better to close everything.
  • david blaine
    david blaine about 11 years
    +1 - for mentioning the consequences of not closing resources.
  • Natix
    Natix about 10 years
    Connection, Stamement and ResultSet all implement AutoCloseable since Java 7.
  • Enerccio
    Enerccio almost 5 years
    this is NOT true. Pooled connections will clean before returning to the pool = closing all their objects except socket connection to RDBMS.