28

Apache Commons DBCP ( commons-dbcp.jar) 接続プールを使用しています。

プールから接続を取得すると、それは class にラップされ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();

上記のコードを実行すると、次の例外が発生します。

java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper は、oracle.sql.ArrayDescriptor.createDescriptor で oracle.jdbc.OracleConnection にキャストできません

ほとんどのサイトやフォーラムで解決策を見つけようとしましたが、満足のいく答えや解決策を得ることができませんでした。

4

11 に答える 11

25

デフォルトでは、DBCP は「実際の」基礎となるデータベース接続インスタンスへのアクセスを許可しないため、Oracle クラスにアクセスできません。

プールを構成するときに、次のように設定できます。

accessToUnderlyingConnectionAllowed = true

そして、それは機能します。

デフォルトは false です。これは潜在的に危険な操作であり、不適切な動作をするプログラムは有害なことを行う可能性があります。(基になる接続を閉じるか、保護された接続が既に閉じられている場合は引き続き使用します) 注意して、ドライバー固有の拡張機能に直接アクセスする必要がある場合にのみ使用してください

注: 元の接続だけを閉じて、基になる接続を閉じないでください。

于 2011-06-27T06:59:25.897 に答える
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;

この時点からoracleConnection、元の の代わりに を使用しconnectionます。

http://docs.oracle.com/javase/6/docs/api/java/sql/Wrapper.htmlを参照してください。

于 2013-01-14T21:48:27.970 に答える
6

この投稿を見ると、次のコードで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ニートがクラスパスにあることを覚えておいてください

于 2012-04-20T00:20:00.490 に答える
5

うーん、私はあなたと同じ解決策を見つけました.2つの立場があると思います. 1.Config 接続プール set accessToUnderlyingConnectionAllowed = "true" ; 2.オープンソースプロジェクトにまつわる悪夢。恐ろしい献身。この場合、つまり

org.apache.commons.dbcp.DelegatingConnection 

等しくない

org.apache.tomcat.dbcp.dbcp.DelegatingConnection

デフォルトのApache common-dbcp.jarでは、次のクラスは見つかりませんが、クラスだけが重要です。そのため、どこかでクラスを見つける必要があります。最終的にパッケージtomcat-dbcp .jar を見つけました。http://www.docjar.com/から 入手できます。

import org.apache.tomcat.dbcp.dbcp.DelegatingConnection

、強制的に 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

とても奇妙なことですが、実際の作業です。

于 2012-04-06T11:47:43.860 に答える
2

アドバイスを探している他の人がこれに対する究極の解決策について知っていることを確認するために、ここにこれを仮定しています:

永続化マネージャーのバンドルされていないバージョンを使用せざるを得ない場合 (古いリポジトリは、バンドルされたレイアウトと互換性のない構造をまだ使用しているため)、ここでできることは、解決策は非常に簡単です。

Jackrabbit Core のソースをダウンロードします (Jackrabbit の Web サイトから入手できます)。 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 (まだ問題がある現在のリリース) に対するバグを記録するようにしました: https://issues.apache.org/jira/browse/JCR-3262

お役に立てれば!

于 2012-03-16T17:16:10.733 に答える
1

オラクルのストアドプロシージャの呼び出しで配列を使用し、オラクル独自の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();
    }

ただし、classpath/dependeciesにはcommons-dbcpが必要です。

    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
        <scope>provided</scope>
    </dependency>
于 2012-05-25T07:44:01.017 に答える
1

私は同じ問題に遭遇しました。Spring を使用していて、NativeJdbcExtractor というクラスがあります。これには多くの実装があり、次の実装は TomCat で機能します。Websphere、Weblogic アプリ サーバーには特定の実装があります。

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

DAO で Bean を注入し、次のメソッドを使用できます

protected NativeJdbcExtractor jdbcExtractor;
Connection conn=jdbcExtractor.getNativeConnection(oracleConnection);
于 2013-10-16T04:14:06.227 に答える
0

私は 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);

ソリューション:

依存関係をtomcat-dbcp 8.5.8 追加し、同じ jar を tomcat の lib フォルダーに追加します。
tomcat には、7.0 以降のバージョンごとに異なる jar があるようです (参照: https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-dbcp )。

それが誰かを助けることを願っています。

于 2016-12-19T10:25:19.737 に答える
0

コンテキスト定義で、以下のタグを既存の xml 定義に追加します。

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

.

于 2015-07-30T11:07:16.667 に答える