Подтвердить что ты не робот

Apache Commons Проблема с объектом соединения DBCP, Thread: ClassCastException в org.apache.tomcat.dbcp.dbcp.PoolingDataSource $PoolGuardConnectionWrapper

Я использую Apache Commons DBCP (commons-dbcp.jar) Пул соединений.

Как только я получил соединение из пула, он завернут в class org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.

Мое требование - передать массив строк в хранимую процедуру pl/sql в Oracle.

Вот что я делаю в следующем фрагменте кода:

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.jdbc.OracleConnection     at oracle.sql.ArrayDescriptor.createDescriptor

Я попытался найти решение по этому поводу на всех сайтах и ​​форумах, но не смог получить удовлетворенный ответ или решение на том же уровне.

4b9b3361

Ответ 1

По умолчанию, DBCP не разрешает доступ к "реальному" базовому подключению к базе данных, поэтому вы не можете попасть в класс Oracle.

Когда настраивает пул, вы можете установить

accessToUnderlyingConnectionAllowed = true

а затем он работает.

По умолчанию это ложь, это потенциально опасная операция, а неправильные программы могут делать вредные вещи. (закрытие основного или продолжение его использования, когда защищенное соединение уже закрыто) Будьте осторожны и используйте их только в том случае, если вам нужен прямой доступ к конкретным расширениям драйвера

ПРИМЕЧАНИЕ. Не закрывайте базовое соединение, только оригинальное.

Ответ 2

Если вы используете JDBC-соединение, совместимое с Java 6, вы можете использовать следующий код:

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

Ответ 3

В этом сообщении я могу получить 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 находится в пути класса

Ответ 4

Хммм, я встречаю то же самое, что и вы. Я думаю, что вам нужно сделать две позиции, о которых вы говорите. 1.Config Connection pool 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

Это такая странная вещь, но реальная работа в этом деле.

Ответ 5

Я предлагаю это здесь, чтобы убедиться, что кто-то, кто ищет советы, знает о конечном решении этого вопроса:

Если вы вынуждены использовать не связанную версию диспетчера персистентности (поскольку старый репозиторий по-прежнему использует эту структуру, которая несовместима с компоновкой в ​​комплекте), вот что вы можете сделать, решение довольно просто:

Загрузите источники для 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+, чтобы скомпилировать источники, я сделал это и не имел проблем с зависимостью, обратите внимание, что я скомпилировал версию 2.2.10 Jackrabbit.

Я также позаботился, чтобы зарегистрировать ошибку против Jackrabbit 2.2.11 (текущая версия, которая все еще имеет проблему): https://issues.apache.org/jira/browse/JCR-3262

Надеюсь, это поможет!

Ответ 6

Мы используем массивы в наших вызовах для хранения оракулов и используем apacle для создания массивов. Эта небольшая проверка устраняет проблему для нас при использовании функций из автономных приложений, используя 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 в pathpath/dependecies.

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

Ответ 7

Я столкнулся с той же проблемой. Мы использовали 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);

Ответ 8

в вашем определении контекста добавьте теги ниже в существующее определение xml.

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

.

Ответ 9

Для остальных, getDelegate() и getInnermostDelegate() оба возвращают NULL в мой код. Однако из отладчика я нашел OracleConnection, как показано ниже. Мы используем Spring JdbcTemplate во всем приложении, в которое вводится источник данных. Мы находимся на spring -jdbc-4.1.5.RELEASE.jar и ojdbc6.jar.

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

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

Ответ 10

Я работаю с 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 и добавьте ту же самую банку в папку lib из tomcat.
Кажется, у tomcat разные банки для разных версий, начиная с 7.0 (ссылка: https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-dbcp).

Надеюсь, что это поможет кому-то.