SqlStructArrayValue:在Oracle存储过程中向结构数组传递对象列表。

问题描述 投票:1回答:1

我使用JDBCTemplate来创建连接池,并获得 java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to oracle.jdbc.OracleConnection


我试图使用spring数据扩展包将Java中的对象列表传递给Oracle中的一个过程。


步骤如下 在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.

arrays oracle struct spring-data procedure
1个回答
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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.