我使用JDBCTemplate来创建连接池,并获得 java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to oracle.jdbc.OracleConnection
步骤如下 在Oracle中创建一个数组和结构。在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上下文文件: 增加了accessToUnderlyingConnectionAllowed=true 2. 在DAO implic中创建了函数:
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,你将能够通过使用JDBCTemplate创建的Poolable连接转为常规Oracle连接。((DelegatingConnection)conn).getInnermostDelegate()。 传递给数组描述符对象的连接中。签发: 上述java函数在执行行失败,抛出这个异常。 java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to oracle.jdbc.OracleConnection
先谢谢你 Sam.I am using JDBCTemplate to create connection pool and get java.lang.ClassCastException: org.apache.ClassCastException.
你正在使用第三方连接池与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);
}
}