Reputation: 2803
Just as the title says, I was wondering why a prepared statements .isClosed() method will return false after closing the underlying stream (Using JDBC).
public void someTest() throws SQLException, InterruptedException {
Connection conn = DBHelper.newConnection();
PreparedStatement statement = conn.prepareCall(CLEANUP_DELETE);
conn.close();
System.out.println(statement.isClosed());
Thread.sleep(1000);
System.out.println(statement.isClosed());
}
Output
false
false
But if you attempt to invoke a set method or an execute you get this:
java.sql.SQLException: org.apache.commons.dbcp.DelegatingCallableStatement with address: "SQLServerCallableStatement:32" is closed.
at org.apache.commons.dbcp.DelegatingStatement.checkOpen(DelegatingStatement.java:137)
at org.apache.commons.dbcp.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:120)
at org.apache.commons.dbcp.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:120)
at com.ipti.ptl.common.messagetable.MessageHandlerTest.someTest(MessageHandlerTest.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606) .....
Upvotes: 1
Views: 2542
Reputation: 9816
This might be a bug with the DBCP library, although I would have to look at the JDBC spec. Have you tried using native JDBC PreparedStatement
for your driver?
EDIT:
Looking at the MySQL connector source code (available here) it looks like the implementation of Connection.close()
actually closes all the statements associated with the connection. So when using the MySQL JDBC driver, PreparedStatement.isClosed()
will return true if the connection was closed. I am not quite sure what the JDBC specification says about this though.
In your case, I am not sure if the DBCP library is delegating the call to isClosed()
to the underlying driver or not, that's why I recommend removing this extra layer and see what happens. If there is a bug in DBCP, I would report it. If there is a bug in the underlying driver you are using, I would report that too. Assuming this would be a bug indeed.
EDIT 2:
Per the comments, the JDBC 4.1 specification says (section 9.4.4.1):
Connection.close
An application calls the method Connection.close() to indicate that it has finished using a connection. All Statement objects created from a given Connection object will be closed when the close method for the Connection object is called.
So I would expect the statement to be indeed closed. So there is a bug either in the DBCP library or the MS SQL Server driver in use.
Upvotes: 2