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

[21 Sep 2005 12: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 13:28] Vasily Kishkin
I was able to reproduce the bug. Thanks for the bug report. Test case is attached.
[22 Sep 2005 13:29] Vasily Kishkin
Test case

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

[22 Sep 2005 15: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 15: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 15: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 16: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 21:52] Mark Matthews
Fixed in 3.1.11.