Question

It is generally considered a good practice to reuse CallableStatement's instances (check here).

But when creating a CallableStatement, that statement (from my understanding) is bound to a specific Connection. So we usually do:

Connection con = pool.getConnection();
CallableStatement st = con.prepareCall("{ some stmt; }");
st.executeQuery();
st.close();
con.close();            

From what I checked, the following is not going to execute the query:

Connection con = pool.getConnection();
CallableStatement st = con.prepareCall("{ some stmt; }");
con.close();
con = pool.getConnection(); // possibly another new connection, different than the one used to create the CallableStatement instance
st.executeQuery();
st.close();

My question is: if I want to reuse all my CallableStatement instances, but on the other hand still being able to get new connections and close the old ones (not have always have the same connection open) what can I do?

Was it helpful?

Solution

PreparedStatements are (or ought to be) cached by your JDBC driver. See e.g. http://www.mchange.com/projects/c3p0/

This means you should not hold on to one and use between connections, but don't worry, your driver will manage caching for you. Essentially what happens is each connection will cache its own, so if you have 5 connections, you'll have 5 cached copies lying around, which is probably sufficiently small.

Calling prepareStatement will retrieve from cache if cached and allocate if not. So repeated calls to prepareStatement are lightweight. This is the correct use of the API.

See e.g. Oracle's docs which is technically Oracle-specific but I believe this information is standard.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top