我使用JDBCTemplate创建连接池并获取java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to oracle.jdbc.OracleConnection
遵循的步骤
在Oracle中创建了一个数组和结构
使用创建的数组:
DROP TYPE SCHEMA_NAME.TB_T_TYPE;
CREATE OR REPLACE TYPE SCHEMA_NAME.TB_T_TYPE is table of T_TYPE;
/
使用创建的结构:
DROP TYPE SCHEMA_NAME.T_TYPE;
CREATE OR REPLACE TYPE SCHEMA_NAME.T_TYPE is object (
NAME VARCHAR2(100),
ATTRIBUTE1 VARCHAR2(100),
ATTRIBUTE2 VARCHAR2(100)
)
/
在架构级别中创建了一个程序:
CREATE OR REPLACE procedure SCHEMA_NAME.POPULATE_TABLE_TEST (example TB_T_TYPE) as
type t_tb_seq is table of number;
l_t_seq t_tb_seq := t_tb_seq();
begin
for i in 1.. example.count loop
l_t_seq.extend;
select 1 into l_t_seq(i) from dual;
end loop;
forall i in 1.. example.count
insert into TABLE_TEST(id,name,attribute1,attribute2)
values (l_t_seq(i),
treat(example(i) as T_TYPE).NAME,
treat(example(i) as T_TYPE).ATTRIBUTE1,
treat(example(i) as T_TYPE).ATTRIBUTE2
);
end;
/
爪哇
1. Spring Context文件:我添加了accessToUnderlyingConnectionAllowed = true
2. 在DAO impl中创建的功能:
private final String ORACLE_STRUCT = "SEATMGR.T_TYPE ";
private final String ORACLE_ARRAY = "SEATMGR.TB_T_TYPE";
@SuppressWarnings("unchecked")
public void testingArray(List<SeatAssignmentDetails> assignmentDetails) throws Exception {
SimpleJdbcCall simpleJdbcCall;
try {
List<TestObject> objects = new ArrayList<TestObject>();
TestObject[] testArray = new TestObject[assignmentDetails.size()];
int i = 0;
for (SeatAssignmentDetails seatAssignmentDetails : assignmentDetails) {
TestObject obj = new TestObject();
obj.setCity(seatAssignmentDetails.getCity());
obj.setSite(seatAssignmentDetails.getSite());
obj.setState(seatAssignmentDetails.getState());
testArray[i] = obj;
i++;
}
simpleJdbcCall = new SimpleJdbcCall(
sspaDBConnection.getJDBCTemplate());
StructMapper<TestObject> mapper = new BeanPropertyStructMapper<TestObject>();
simpleJdbcCall
// .withCatalogName("pkg_SSEQ_queries")
.withProcedureName("POPULATE_TABLE_TEST")
.withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter("example",Types.ARRAY,ORACLE_ARRAY));
simpleJdbcCall.execute(new MapSqlParameterSource().addValue(
"example", new SqlStructArrayValue<TestObject>(
testArray, mapper,
ORACLE_STRUCT, ORACLE_ARRAY)));
} catch (Exception e) {
logger.error("Horrible errrrrrr",e);
}
}
我一直在阅读如果你在不使用SimpleJdbcCall的情况下使用常规过程调用,你将能够使用((DelegatingConnection)conn)将JDBCTemplate创建的Poolable连接转换为常规Oracle连接.getInnermostDelegate(); 在传递给数组描述符对象的连接中。
问题:
抛出此异常,上述java函数在执行行上失败:
java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to oracle.jdbc.OracleConnection
提前致谢。
萨姆。
答案 0 :(得分:0)
您正在使用第三方连接池来使用Oracle RDBMS。
SqlStructArrayValue
应该和OracleConnection
一起使用。
因此,您需要从连接池中取消物理连接。
OracleConnection oconn = conn.unwrap(OracleConnection.class);
在这种情况下,您需要扩展SqlStructArrayValue
并从连接池中解包OracleConnection
。
public class OracleSqlStructArrayValue<T> extends SqlStructArrayValue {
public OracleSqlStructArrayValue(T[] values, StructMapper<T> mapper, String structTypeName) {
super(values, mapper, structTypeName);
}
public OracleSqlStructArrayValue(T[] values, StructMapper<T> mapper, String structTypeName, String arrayTypeName) {
super(values, mapper, structTypeName, arrayTypeName);
}
@Override
protected Object createTypeValue(Connection conn, int sqlType, String typeName) throws SQLException {
if (!conn.isWrapperFor(OracleConnection.class)) {
throw new SQLFeatureNotSupportedException("Oracle types supports only OracleConnection");
}
OracleConnection oconn = conn.unwrap(OracleConnection.class);
return super.createTypeValue(oconn, sqlType, typeName);
}
}