当需要 nativeJdbcExtractor 时,Spring 5 JDBC 方法是啥?
Posted
技术标签:
【中文标题】当需要 nativeJdbcExtractor 时,Spring 5 JDBC 方法是啥?【英文标题】:What is the Spring 5 JDBC approach when nativeJdbcExtractor is needed?当需要 nativeJdbcExtractor 时,Spring 5 JDBC 方法是什么? 【发布时间】:2018-10-22 01:10:42 【问题描述】:我刚刚升级了 Spring/SpringBoot 依赖项,并注意到 JdbcTemplate 类不再具有属性“nativeJdbcExtractor”。
我能够找到详细信息和背景: https://jira.spring.io/browse/SPR-14670
但是我找不到替换配置。我使用 commons-dbcp 库和 Spring 类,如 SimpleJdbcCall 等。我从不处理低级 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 类中获得的,因此不受我的控制。
replacement for jdbc.support.nativejdbc remove in Spring 5
更新 #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();
【问题讨论】:
【参考方案1】:新功能:
您似乎正在使用来自spring-data-jdbc-ext
的org.springframework.data.jdbc.support.oracle.SqlArrayValue
。错误在那里,展开应该在那里发生。
类似下面的东西(未经测试)
protected Object createTypeValue(Connection conn, int sqlType, String typeName)
throws SQLException
return conn.unwrap(OracleConnection.class).createArray(typeName, values);
关于 JDBC 驱动:
您使用的是 Java 8 或更高版本,因为 Spring 5 需要 Java 8。因此您应该使用 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 的驱动程序互操作性矩阵,您会发现该潜水员也适用于较旧的数据库。
旧的/过时的:
在执行转换而不是转换调用 #unwrap
的代码中。所以不是
OracleConnection oracleConnection = (OracleConnection) connection;
打电话
OracleConnection oracleConnection = connection.unwrap(OracleConnection.class);
在堆栈跟踪中,您会看到谁在执行强制转换,这将在您的代码中,因为SimpleJdbcCall
和朋友不会大小写为OracleConnection
。问题不在于JdbcTemplate
,而是你的代码在做演员。
【讨论】:
谢谢 - 但这让我感到困惑 - 我已经这样做了,我检查了堆栈跟踪,发现转换不在我的代码中,我并不感到惊讶,因为我从不处理原始连接类型。请看一下堆栈跟踪 - 你可以看到它在 Spring 代码调用的 JDBC 驱动程序代码中......如果可以使用“nativeJdbcExtractor”属性,这很有效,但不适用于 Spring 5+。 检查是否有 JDBC 驱动程序更新,因为我使用的是 ojdbc6 (11.2.0.4),它看起来很最新。 升级到 12.2.0.1 没有帮助 - 此版本具有相同的转换代码。这就是为什么我认为 Spring 删除“nativeJdbcExtractor”特性为时过早——Oracle JDBC 驱动程序已通过 Java 8 认证,但它们的代码不使用 Connection.unwrap() ... 对框架/池库不友好 检查 Spring 依赖(升级)。 当然,这个bug还在源spring-data-jdbc-ext
你需要写一个自定义版本的SqlArrayValue
。以上是关于当需要 nativeJdbcExtractor 时,Spring 5 JDBC 方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章