1

I'm currently creating a lot of classes that will access database using a connection pool. So I get a connection, create a statement and get the result set. (I can't use Java 1.7 and the fantastic Automatic Resource Management) When finishing my method I must finish with a finally block:

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException sqle) {
                logger.error("Couldn't close result set", sqle);
            }
        }
        if (st != null) {
            try {
                st.close();
            } catch (SQLException sqle) {
                logger.error("Couldn't close statement", sqle);
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException sqle) {
                logger.error("Couldn't close connection", sqle);
            }
        }

I'm already seeing the nightmare it will be for XX classes having 4/5 methods each.

Would it be good practice to make an helper class which would got a special close method for each object type like :

public static void closeResource(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException sqle) {
                logger.error("Couldn't close connection", sqle);
            }
        }

And then just doing my usual finally with xx.close(connection);xx.close(statement);xx.close(rs);

Or in the same thinking (I know at this point I'll shock some people as I myself find that a bit ackward), having a method like public static void closeResources(Object... obj) {} with an awful list of instanceof ?

Or in your experience, coding the whole thing everywhere is better ?

Michael Laffargue
  • 10,116
  • 6
  • 42
  • 76

4 Answers4

2

Use overloading.

private void close(ResultSet rSet) throws SQLException {
    if (rSet != null) {
        rSet.close();
    }
}

private void close(Statement statement) throws SQLException {
    if (statement != null) {
        statement.close();
    }
}

private void close(Connection conn) throws SQLException {
    if (conn != null) {
        conn.close();
    }
}

Usage will be much cleaner now:

try {
    // do db stuff
} catch (Exception e) {
    logger.error("log it", e);
} finally {
    close(rs);
    close(cs);
    close(conn);
}
adarshr
  • 61,315
  • 23
  • 138
  • 167
2

Use Apache commons project : http://commons.apache.org/dbutils/apidocs/org/apache/commons/dbutils/DbUtils.html

DbUtils.closeQuietly() is probably what you need

chburd
  • 4,131
  • 28
  • 33
1

Just one more example. Suitable for simple small projects.

Object doRequest() throws SQLException {

    PreparedStatement ps = ... // initialize statement
    try {
        ResultSet rs = ps.executeQuery();
        try {

           // use ResultSet
           return someResult;

        } finally {
           rs.close();
        } 
    } finally {
        ps.close();
    }

}

Although it is not pretends to be complete solution (many nested try-finally are quite unreadable), there are several advantages:

  • Method itself not deals with exception handling. Often only caller may decide what to do with exception.
  • As follows, method always returns correct result or throws exception. No magic "error values" required.
  • Resources closed only if they were initialized. No need to check for null berode close().
lxbndr
  • 2,159
  • 1
  • 15
  • 17
0

You could also exploit the fact that for every class you want to close, the close method has no args, and make a reflective helper method like this:

    public static final void tryClose(Object o){
        if(o != null){
            Method[] m = o.getClass().getMethods();
            for (Method method : m) {
                if("close".equals(method.getName())){
                    if(!method.isAccessible()) method.setAccessible(true);
                    try {
                        method.invoke(o);
                    } catch (Exception e) {
                        System.err.println(e);
                    }
                    break;
                }
            }
        }       
    }

EDIT: Tested with FileWriter, works fine in my machine.

Mister Smith
  • 27,417
  • 21
  • 110
  • 193