Apache Commons DBCP connection object problem, Thread: ClassCastException in org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper

Prodigy picture Prodigy · Jun 27, 2011 · Viewed 53.6k times · Source

I am using Apache Commons DBCP (commons-dbcp.jar) Connection pool.

Once I obtained a connection from the pool it is wrapped in the class org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.

My requirement is to pass an array of Strings to pl/sql stored procedure in Oracle.

Here is what I am doing in the following code snippet:

Connection dbConn = ConnectionManager.ds.getConnection();
//The above statement returns me an connection wrapped in the class
//org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.

org.apache.commons.dbcp.DelegatingConnection del = new org.apache.commons.dbcp.DelegatingConnection(dbConn.getConnection());
con = del.getInnermostDelegate();

cs = con.prepareCall("call SP_NAME(?,?,?,?)");
oracle.sql.ArrayDescriptor arDesc= oracle.sql.ArrayDescriptor.createDescriptor("ARRAY_NAME", (OracleConnection) con);

CallableStatement c_stmt = conn.prepareCall("begin update_message_ids_ota
(:x); end;" );
c_stmt.setArray( 1, array_to_pass );
c_stmt.execute();

On executing the above code, I get the following exception:

java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to oracle.jdbc.OracleConnection at oracle.sql.ArrayDescriptor.createDescriptor

I tried to find out solution over this going throughout almost of the sites and forums, but couldn't get the satisfied answer or solution on the same.

Answer

Thilo picture Thilo · Jun 27, 2011

By default, DBCP does not allow access to the "real" underlying database connection instance, so you cannot get to the Oracle class.

When configuring the pool, you can set

accessToUnderlyingConnectionAllowed = true

and then it works.

Default is false, it is a potential dangerous operation and misbehaving programs can do harmful things. (closing the underlying or continue using it when the guarded connection is already closed) Be careful and only use when you need direct access to driver specific extensions

NOTE: Do not close the underlying connection, only the original one.