Java Apache Commons DBCP连接对象问题,线程:org.Apache.tomcat.DBCP.DBCP.PoolgDataSource$PoolGuardConnectionWrapper中的ClassCastException

Java Apache Commons DBCP连接对象问题,线程:org.Apache.tomcat.DBCP.DBCP.PoolgDataSource$PoolGuardConnectionWrapper中的ClassCastException,java,jdbc,apache-commons-dbcp,Java,Jdbc,Apache Commons Dbcp,我正在使用ApacheCommonsDBCP(Commons DBCP.jar)连接池 一旦我从池中获得了连接,它就被包装在 classorg.apache.commons.dbcp.PoolgDataSource$PoolGuardConnectionWrapper 我的要求是将字符串数组传递给Oracle中的pl/sql存储过程 以下是我在以下代码段中所做的操作: Connection dbConn = ConnectionManager.ds.getConnection(); //The

我正在使用ApacheCommonsDBCP(
Commons DBCP.jar
)连接池

一旦我从池中获得了连接,它就被包装在 class
org.apache.commons.dbcp.PoolgDataSource$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();
在执行上述代码时,我得到以下异常:

java.lang.ClassCastException:org.apache.commons.dbcp.PoolgDataSource$PoolGuardConnectionWrapper不能强制转换为oracle.jdbc.OracleConnection 位于oracle.sql.ArrayDescriptor.createDescriptor


我在几乎所有的网站和论坛上都试图找到解决方案,但没有找到满意的答案或解决方案。

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

当你离开游泳池时,你可以设置

accessToUnderlyingConnectionAllowed = true
然后它就起作用了

默认值为false,这是一种潜在的危险操作,行为不端的程序可能会做有害的事情。(关闭底层连接或在保护连接已关闭时继续使用)请小心,仅在需要直接访问特定于驱动程序的扩展时使用

注意:不要关闭基础连接,只关闭原始连接


我在这里提出这一点是为了确保任何其他寻求建议的人都知道这一问题的最终解决方案:

如果您被迫使用非捆绑版本的持久性管理器(因为旧存储库仍然使用与捆绑布局不兼容的结构),那么您可以做的是,解决方案非常简单:

下载Jackrabbit Core的源代码(您可以从Jackrabbit网站获得) 打开OraclePersistenceManager类并找到以下代码行:

Object blob = createTemporary.invoke(null,
                new Object[]{con, Boolean.FALSE, durationSessionConstant});
(第377行附近-也可以检查StackTrace以供参考)

ConnectionFactory包含一个静态方法,该方法允许打开正是您需要的连接:

Object blob = createTemporary.invoke(null,
                new Object[]{org.apache.jackrabbit.core.util.db.ConnectionFactory
                        .unwrap(con), Boolean.FALSE, durationSessionConstant});
您需要Maven 2+来编译源代码,我这样做了,并且没有依赖性问题,请注意,我编译了Jackrabbit的2.2.10版

我还确保记录了针对Jackrabbit 2.2.11(当前版本仍然存在问题)的错误:


希望这有帮助

嗯,我遇到了和你一样的解决方案。我想有两个位置需要你提及。 1.配置连接池集合accessToUnderlyingConnectionLowed=“true”; 2.关于开源项目的噩梦。这是一个令人难以置信的想法。在这种情况下 是

不等于

org.apache.tomcat.dbcp.dbcp.DelegatingConnection
虽然在默认的ApacheCommondBCP.jar中,您永远找不到下面的类,但只有类才是关键。所以,我们必须在某处找到班级。我最终找到了包tomcatdbcp.jar。你可以从 之后

,您可以强制强制强制转换dbConn并获取基础连接

oracle.jdbc.driver.OracleConnection delConn = 

(oracle.jdbc.driver.OracleConnection) 

((org.apache.tomcat.dbcp.dbcp.DelegatingConnection)c_stmt.getConnection()).getDelegate();
然后我们可以使用delConn获取ArrayDescriptor 记住一件事,在那里,我们不需要

org.apache.commons.dbcp.DelegatingConnection Class

这是一件很奇怪的事情,但实际的案例工作。

看到这篇文章后,我可以通过以下代码获得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();

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

我们在调用oracle存储过程中使用数组,并使用oracle专有api构建数组。这个小检查为我们解决了使用commons dbcp从独立应用程序使用功能时的问题

    if (conn instanceof org.apache.commons.dbcp.DelegatingConnection)
    {
        log.debug("detected apache commons dbcp datasource");
        conn = ((org.apache.commons.dbcp.DelegatingConnection) conn).getInnermostDelegate();
    }
不过,在类路径/依赖项中需要commons dbcp

    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
        <scope>provided</scope>
    </dependency>

公共dbcp
公共dbcp
1.4
假如

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

OracleConnection oracleConnection = null;
try {
    if (connection.isWrapperFor(OracleConnection.class)) {
        oracleConnection = connection.unwrap(OracleConnection.class);
    }
} catch (SQLException ex) {
    // do something
}
return oracleConnection;
从这一点开始,使用
oracleConnection
而不是原来的
连接


参见

我遇到了同样的问题。我们使用的是spring,它有一个名为 NativeJdbcExtractor。它有许多实现,下面的一个适用于TomCat。Websphere、Weblogic和应用程序服务器都有特定的实现

<bean id="jdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"></bean>

在上下文定义中,将以下标记添加到现有xml定义中

factory="oracle.jdbc.pool.OracleDataSourceFactory
scope="Shareable"
type="oracle.jdbc.pool.OracleDataSource"

.

对于其他正在查看的人,
getDelegate()
getInnermostDelegate()
都在我的代码中返回
NULL
。但是,从调试器中,我发现OracleConnection如下所示。我们在整个应用程序中使用SpringJDBCTemplate,其中注入了数据源。我们使用的是spring-jdbc-4.1.5.RELEASE.jar和ojdbc6.jar

Connection conn = getJdbcTemplate().getDataSource().getConnection();

OracleConnection oracleConnection = ( OracleConnection ) conn.getMetaData().getConnection();

我正在使用tomcat 8.5.8,并面临这个问题。
下面的解决方案非常有效


代码:

Delegating Connection delegate_conn = new Delegating Connection(connection)
conn = delegate_conn.getInnermostDelegate();
oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor("TABLE_VIEW", conn);

解决方案:

Delegating Connection delegate_conn = new Delegating Connection(connection)
conn = delegate_conn.getInnermostDelegate();
oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor("TABLE_VIEW", conn);
为tomcat dbcp 8.5.8添加依赖项 并在tomcat的lib文件夹中添加相同的jar。
从7.0开始,tomcat对于不同的版本似乎有不同的JAR(参考:)


希望它能帮助别人。

我正在使用java7&ojdbc7.jar&tomcat8

在转换((OracleConnection)connection.createARRAY时,我在tomcat中遇到了同样的问题

在搜索了很多解决方案和论坛后,我最终找到的解决方案是

Connection connection = datasource.getConnection();
CallableStatement cs = connection.prepareCall("{ CALL PKG.PROCEDURE(?)}");

if(cs.getConnection().isWrapperFor(OracleConnection.class)) {
  OracleConnection orConn = cs.getConnection().unwrap(OracleConnection.class);
  orConn.createARRAY ..// is working perfectly.

}
如果您执行了connection.isWrapperFor(OracleConnection.class)操作,您将得到false。您需要使用cs.getConnection


可能会对某人有所帮助。

我在资源详细信息中使用了以下参数,但仍然不起作用。initialSize=“5”maxActive=“5”minidle=“5”maxWait=“20000”removeAbandoned=“true”removeAbandonedTimeout=“60”maxIdleTime=“3000”accesstoUnderlyingConnectionLowed=“true”@Prodigy您有解决方案吗?我也面临着同样的问题。请注意。此解决方案仅适用于以下情况:
Delegating Connection delegate_conn = new Delegating Connection(connection)
conn = delegate_conn.getInnermostDelegate();
oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor("TABLE_VIEW", conn);
Connection connection = datasource.getConnection();
CallableStatement cs = connection.prepareCall("{ CALL PKG.PROCEDURE(?)}");

if(cs.getConnection().isWrapperFor(OracleConnection.class)) {
  OracleConnection orConn = cs.getConnection().unwrap(OracleConnection.class);
  orConn.createARRAY ..// is working perfectly.

}