Apache Commons DBCP连接对象问题,org.apache.tomcat.dbcp.dbcp.PoolingDataSource中的Thread:ClassCastException $ PoolGuardConnectionWrapper

Pro*_*igy 28 java jdbc apache-commons-dbcp

我正在使用Apache Commons DBCP(commons-dbcp.jar)连接池.

一旦我从池中获得了连接,它就会被包含在课堂中org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.

我的要求是将一个字符串数组传递给Oracle中的pl/sql存储过程.

以下是我在以下代码片段中所做的事情:

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();
Run Code Online (Sandbox Code Playgroud)

在执行上面的代码时,我得到以下异常:

java.lang.ClassCastException:org.apache.commons.dbcp.PoolingDataSource $ PoolGuardConnectionWrapper无法在oracle.sql.ArrayDescriptor.createDescriptor中强制转换为oracle.jdbc.OracleConnection

我试图在几乎所有的网站和论坛中找到解决方案,但无法得到满意的答案或解决方案.

Thi*_*ilo 25

默认情况下,DBCP不允许访问"真正的"底层数据库连接实例,因此您无法访问Oracle类.

配置池,可以设置

accessToUnderlyingConnectionAllowed = true
Run Code Online (Sandbox Code Playgroud)

然后它的工作原理.

默认是假的,这是一个潜在的危险操作,行为不端的程序可以做有害的事情.(在保护连接已经关闭时关闭底层或继续使用它)小心并且仅在需要直接访问驱动程序特定扩展时使用

注意:不要关闭底层连接,只关闭原始连接.


Jef*_*son 18

如果您使用的是Java 6兼容JDBC连接,则可以使用以下代码:

OracleConnection oracleConnection = null;
try {
    if (connection.isWrapperFor(OracleConnection.class)) {
        oracleConnection = connection.unwrap(OracleConnection.class);
    }
} catch (SQLException ex) {
    // do something
}
return oracleConnection;
Run Code Online (Sandbox Code Playgroud)

从这一点开始,使用oracleConnection而不是原始connection.

请参阅http://docs.oracle.com/javase/6/docs/api/java/sql/Wrapper.html


Rui*_*Zha 5

嗯?我遇到了和您一样的解决方案。我认为有两个职位需要您提及。1.Config连接池设置accessToUnderlyingConnectionAllowed =“ true”; 2.有关开源项目的噩梦。土地调和。在这种情况下

org.apache.commons.dbcp.DelegatingConnection 
Run Code Online (Sandbox Code Playgroud)

不等于

org.apache.tomcat.dbcp.dbcp.DelegatingConnection
Run Code Online (Sandbox Code Playgroud)

而在默认的apache common-dbcp.jar中,您将永远找不到跟随类。但是,只有该类才是关键。因此,我们必须在某个地方找到类。我最终找到了包tomcat-dbcp .jar。你可以从它http://www.docjar.com/

import org.apache.tomcat.dbcp.dbcp.DelegatingConnection
Run Code Online (Sandbox Code Playgroud)

,您可以强制将您的dbConn强制转换为基础连接

oracle.jdbc.driver.OracleConnection delConn = 

(oracle.jdbc.driver.OracleConnection) 

((org.apache.tomcat.dbcp.dbcp.DelegatingConnection)c_stmt.getConnection()).getDelegate();
Run Code Online (Sandbox Code Playgroud)

然后我们可以使用delConn来获取ArrayDescriptor记住一件事,在这里,我们不需要

org.apache.commons.dbcp.DelegatingConnection Class
Run Code Online (Sandbox Code Playgroud)

这是一件很奇怪的事情,但对案件来说却是真正的工作。


小智 5

看到这篇文章,我可以使用以下代码获取OracleConnection:

DataSource ds1 = // get the org.apache.commons.dbcp.PoolingDataSource
org.apache.tomcat.dbcp.dbcp.DelegatingConnection del = new org.apache.tomcat.dbcp.dbcp.DelegatingConnection(cds1.getConnection());
OracleConnection con = (OracleConnection) del.getInnermostDelegate();
Run Code Online (Sandbox Code Playgroud)

记住commons-dbcp-1.4.jar neet是在类路径中