我刚刚升级了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(); }
新:
看来您正在使用org.springframework.data.jdbc.support.oracle.SqlArrayValuefrom spring-data-jdbc-ext。错误在那里,展开应该在那里发生。
org.springframework.data.jdbc.support.oracle.SqlArrayValue
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。所以代替
#unwrap
OracleConnection oracleConnection = (OracleConnection) connection;
呼叫
OracleConnection oracleConnection = connection.unwrap(OracleConnection.class);
在堆栈跟踪中,您可以看到谁在执行强制类型转换,这将在您的代码中,因为SimpleJdbcCall和朋友不区分OracleConnection。问题不在,JdbcTemplate而是您的代码进行了强制转换。
SimpleJdbcCall
OracleConnection
JdbcTemplate