小编典典

当需要nativeJdbcExtractor时,Spring 5 JDBC方法是什么?

spring-boot

我刚刚升级了Spring / SpringBoot依赖项,并注意到类JdbcTemplate不再具有属性“ nativeJdbcExtractor”。

我能够找到详细信息和背景:https :
//jira.spring.io/browse/SPR-14670

但是,我找不到替换配置。我使用commons-dbcp库和诸如 SimpleJdbcCall 之类的Spring类。我从不处理底层JDBC
API,但是,如果供应商代码需要其实际的连接类型(Oracle),则 nativeJdbcExtractor 设置可确保将其 带入
Spring JDBC代码的深处(不是我的应用代码)。如果我需要Spring API像过去那样自动处理此问题,我不确定如何通过调用
connection.unwrap() 解决此问题。

java.lang.ClassCastException:org.apache.commons.dbcp2.PoolingDataSource $
PoolGuardConnectionWrapper无法转换为oracle.jdbc.OracleConnection

那是隐藏在DataSource配置中的某个地方吗?我已经从commons-dbcp 1.4升级到commons-
dbcp2,但到目前为止找不到任何有用的信息(BasicDataSource)。

更新:
以下线程是相关的,但是由于Connection对象是在JdbcTemplate类内获取的,因此超出了我的控制范围,因此我无法消化正在寻找的答案。

更新#2-堆栈跟踪

Caused by: java.lang.ClassCastException: org.apache.commons.dbcp2.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to oracle.jdbc.OracleConnection
at oracle.sql.TypeDescriptor.setPhysicalConnectionOf(TypeDescriptor.java:832)
at oracle.sql.TypeDescriptor.<init>(TypeDescriptor.java:586)
at oracle.sql.ArrayDescriptor.<init>(ArrayDescriptor.java:224)
at org.springframework.data.jdbc.support.oracle.SqlArrayValue.createTypeValue(SqlArrayValue.java:90)
at org.springframework.jdbc.core.support.AbstractSqlTypeValue.setTypeValue(AbstractSqlTypeValue.java:60)
at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:293)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:232)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:147)
at org.springframework.jdbc.core.CallableStatementCreatorFactory$CallableStatementCreatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:200)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1048)
at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1104)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:414)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:397)
at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:193)

更新#3-执行强制转换的代码(Oracle JDBC)

    public void setPhysicalConnectionOf(Connection var1) {
    this.connection = ((oracle.jdbc.OracleConnection)var1).physicalConnectionWithin();
}

阅读 1207

收藏
2020-05-30

共1个答案

小编典典

新:

看来您正在使用org.springframework.data.jdbc.support.oracle.SqlArrayValuefrom
spring-data-jdbc-ext。错误在那里,展开应该在那里发生。

如下所示(未经测试)

protected Object createTypeValue(Connection conn, int sqlType, String typeName)
        throws SQLException { 
    return conn.unwrap(OracleConnection.class).createArray(typeName, values);
}

关于JDBC驱动程序:

您正在使用Java 8或更高版本,因为Spring 5需要Java8。因此,您应该使用ojdbc8(8表示Java
8)。我强烈建议使用http://www.oracle.com/technetwork/database/application-
development/jdbc/downloads/index.html中的最新12.2.0.1驱动程序。

如果您从http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-
faq-090281.html#01_02检查驱动程序互操作性矩阵,您会发现该diver也适用于较旧的数据库。

旧/过时:

在执行强制转换而不是强制调用的代码中#unwrap。所以代替

OracleConnection oracleConnection = (OracleConnection) connection;

呼叫

OracleConnection oracleConnection = connection.unwrap(OracleConnection.class);

在堆栈跟踪中,您可以看到谁在执行强制类型转换,这将在您的代码中,因为SimpleJdbcCall和朋友不区分OracleConnection。问题不在,JdbcTemplate而是您的代码进行了强制转换。

2020-05-30