Bug #13374 ResultSet::getStatement() on closed result set
Submitted: 21 Sep 2005 10:08 Modified: 17 Oct 2005 19:52
Reporter: Christian Franzel Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:3.1.10 OS:Microsoft Windows (Windows 2000)
Assigned to: Mark Matthews

[21 Sep 2005 10:08] Christian Franzel
Description:
In contrast to older versions (I know this only for 2.0.14) 3.1.10 does not return the owning statement anymore via ResultSet::getStatement() after being closed.

JavaDoc says: return the Statment object that produced this ResultSet object or null if the result set was produced some other way.

It is not explicitly stated what should happen after the resultSet has been closed so this might not be a bug.

This may have implications on releasing ressources - see Bug #13204.

How to repeat:
Statement stmt = ...;
ResultSet resultSet = stmt.executeQuery(sql);
//
Statement stmtBeforeClose = resultSet.getStatement();
resultSet.close();
Statement stmtAfterClose = resultSet.getStatement();
// notice that stmtBeforeClose != null and stmtAfterClose == null

Suggested fix:
getStatement() should (IMHO) return the owning statement according to spec(?)
[22 Sep 2005 11:28] Vasily Kishkin
I was able to reproduce the bug. Thanks for the bug report. Test case is attached.
[22 Sep 2005 11:29] Vasily Kishkin
Test case

Attachment: Bug13374.java (text/java), 1.10 KiB.

[22 Sep 2005 13:00] Mark Matthews
The JDBC documentation specifically states that ResultSet.close() releases JDBC resources associated with the ResultSet, which includes the reference to the statement that created it.

"Releases this ResultSet object's database and JDBC resources immediately instead of waiting for this to happen when it is automatically closed"

If this weren't the case, it would lead to even _more_ memory leaks as there would be dangling references to the Statement that would not be cleared.

I'll poll some other vendors to see how they interpret the requirements, but I have a feeling that this isn't actually a bug.
[22 Sep 2005 13:47] Christian Franzel
>>>
The JDBC documentation specifically states that ResultSet.close() releases JDBC
resources associated with the ResultSet
<<<

yes...

>>>
which includes the reference to the
statement that created it.
<<<

That is "only" an interpretation. Not sure if that is valid. Many method invocations of course throw an SQLException on a closed ResultSet without explicitly stating it, so it may be OK to use that as an argument that getStatement() on a closed ResultSet can return null without violating the interface contract ("returns the statement that created the ResultSet..."), but to me that does not feel correct.

>>>
If this weren't the case, it would lead to even _more_ memory leaks as there
would be dangling references to the Statement that would not be cleared.
<<<

(I assume you are referring to the Bug #13204)
You have to release both the ResultSet and the Statement (ok, I know that you can release the ResultSet by releasing the Statement), so I see no point here in the reference. The problem is NOT that the statement is referenced by the ResultSet, but that the Statement was not released - maybe (and that was my link here) because old code did rely on the assumption that getStatement() does work on a closed ResultSet. I my case it was actually "causing" OOM-Exceptions when upgrading to JConnector 3.1.10 (from a quite old version). It was no big deal and easy to spot and modify, but maybe other developers a facing that problem too...

>>>
I'll poll some other vendors to see how they interpret the requirements, but I
have a feeling that this isn't actually a bug.
<<<

I am not sure either if that is really a bug (and I will not invoke *any* method anymore on a closed ResultSet :-) but as it is a change(!) caused somewhere in the transition to 3.1.10 (or earlier, sorry can't spot that right now) causing problems in formerly working code which was NOT really relying on side effects but on the specification, it is at least something to think about.

BTW: The Oracle JDBC driver does return the creating Statement after ResultSet::close() - but that of course does not judge about "right" and "wrong"...
[23 Sep 2005 13:48] Mark Matthews
The JDBC-4.0 spec (still a work-in-progress) has the following requirement for ResultSet.close(), so at least it's a bit more specific:

"Once a ResultSet has been closed, any attempt to access any of its methods with the exception of the isClosed  method will result in a SQLException being thrown. ResultSetMetaData instances that were created by a ResultSet that has been closed are still accessible."

We'll work on changing the default behavior of ResultSet.getStatement() for JDBC-4.0. I'm going to do some investigation into how hard it would be to have this behavior be user-selectable for drivers that support JDBC-3.0 and earlier.
[23 Sep 2005 14:53] Christian Franzel
>>
The JDBC-4.0 spec (still a work-in-progress) has the following requirement for
ResultSet.close(), so at least it's a bit more specific:
<<
yes... it is more than that - no room for interpretation in 4.0... thanks for your time.
[17 Oct 2005 19:52] Mark Matthews
Fixed in 3.1.11.