tags:

views:

130

answers:

1

Does closing a java.sql.Connection also close all the statements, prepared statements, etc. obtained from that connection? Or is there going to be memory leak if I close the connection but leave the statements, etc. unclosed?

+3  A: 

Does closing a java.sql.Connection also close all the statements, prepared statements, etc. obtained from that connection? Or is there going to be memory leak if I close the connection but leave the statements, etc. unclosed?

You should not depend on it.

The spec reads as follows:

An application calls the method Statement.close to indicate that it has finished processing a statement. All Statement objects will be closed when the connection that created them is closed. However, it is good coding practice for applications to close statements as soon as they have finished processing them. This allows any external resources that the statement is using to be released immediately.

The best practice is to close ALL ResultSets, Statements, and Connections in a finally block, each enclosed in their own try/catch, in reverse order of acquisition.

Write a class like this:

public class DatabaseUtils
{
    public static void close(Statement s)
    {
        try
        {
            if (s != null)
            {
                s.close();
            }
        }
        catch (SQLException e)
        {
            // log or report in someway
            e.printStackTrace();
        }
    }

    // similar for ResultSet and Connection
}

Call like this:

Statement s;
try
{
    // JDBC stuff here
}
finally
{
    DatabaseUtils.close(s);
}
duffymo
@duffymo: Is there an official doc available where I can find more info on this?
Bytecode Ninja
Maybe the JDBC spec, but if the vendor implementing yours decides not to follow the recommendation you'll have issues. What does it matter what official documents say in that case? Just curious - why is this answer not authoritative enough for you?
duffymo
Well, here's what the spec says: 13.1.4 Closing Statement Objects --- An application calls the method Statement.close to indicate that it has finished processing a statement. All Statement objects will be closed when the connection that created them is closed. However, it is good coding practice for applications to close statements as soon as they have finished processing them. This allows any external resources that the statement is using to be released immediately.
Bytecode Ninja
Could you please update your answer and add the text in section 13.1.4 so I can mark it as the answer? Thanks.
Bytecode Ninja
Yuck. Use the Execute Around idiom to abstract the resource and exception handling nonsense as other assorted potential code duplications. Playing about with `null`s is nasty.
Tom Hawtin - tackline
Certainly there's a lot that can be done to reduce boilerplate here. But there's no indication that the OP is at that spot yet. If you have to ask whether or not resources need to be closed, you're probably not ready for "execute around" idiom.
duffymo
Actually I most often use Spring and let Spring manage my connections. But the last time I had read a JDBC book was ages ago and I thought I had read somewhere that closing connections close Statements, Resultsets, etc. as well. However for some reason recently I had started to doubt that and I was wondering if somebody else can reassure me about this. Turns out that all I needed was to look at the JDBC spec to find out. Which duffymo kinda pushed me to do so :)
Bytecode Ninja
Spring is indeed doing all that for you. That's the best feature of the Spring JDBC design: eliminating boilerplate. Rod Johnson hated writing it on his consulting engagements as much or more than you do, so he figured out a good way to do it once.
duffymo
'If the vendor implementing yours decides not to follow the recommendation'. The vendor doesn't have that choice, and it's not a 'recommendation', it's a specification. Vendors must comply.
EJP
My experience is that people have trouble with Oracle JDBC drivers if they don't close resources like this. I haven't read the source code to see if "must" applies here. It's easier to follow this idiom than rail about something that's not under my control.
duffymo