2023-01-18 21:39

springboot调用Oracle存储过程,使用hikari时如何获取oracle.jdbc.OracleConnection

王姐姐

JavaEE

(678)

(0)

收藏

oracle中有个传入数组的存储过程:

定义了类型如下(类型头和类型体均一样):

create or replace type msg_array as TABLE OF NUMBER;

定义了存储过程如下:

CREATE OR REPLACE PROCEDURE MODIFYSAL(M_ARRAY MSG_ARRAY) IS
BEGIN
  FOR I IN 1 .. M_ARRAY.COUNT LOOP
  
    UPDATE EMP SET SAL = SAL + 100 WHERE EMPNO = M_ARRAY(I);
  
  END LOOP;
  COMMIT;
EXCEPTION
  WHEN OTHERS THEN
  
    ROLLBACK;
  
END MODIFYSAL;


在springboot项目中,使用JdbcTemplate调用oracle存储过程时,报如下错误:

image.png

java.lang.ClassCastException: class com.zaxxer.hikari.pool.HikariProxyConnection cannot be cast to class oracle.jdbc.OracleConnection (com.zaxxer.hikari.pool.HikariProxyConnection and oracle.jdbc.OracleConnection are in unnamed module of loader 'app')

调用代码如下:

public void updateSal(List<Integer> empnos){
    String sql = "call modifysal(?)";
    jdbcTemplate.execute(
    new CallableStatementCreator() {

        @Override
        public CallableStatement createCallableStatement(Connection con) throws SQLException {
            
            String sql = "{call modifysal(?)}";
            CallableStatement cs = con.prepareCall(sql);
            ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("MSG_ARRAY", con);
            ARRAY vArray = new ARRAY(tabDesc, con, empnos.toArray());
            cs.setArray(1,vArray);           
            return cs;
        }
    },
    new CallableStatementCallback<Object>() {

        @Override
        public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
            cs.execute();
            return null;
        }
    });
}

这是因为HikariProxyConnection不能转为OracleConnection,需要获取OracleConnection执行才行,修改代码如下:

public void updateSal(List<Integer> empnos){
    String sql = "call modifysal(?)";
    jdbcTemplate.execute(
    new CallableStatementCreator() {

        @Override
        public CallableStatement createCallableStatement(Connection con) throws SQLException {

            OracleConnection conn = con.unwrap(OracleConnection.class);
            String sql = "{call modifysal(?)}";
            CallableStatement cs = con.prepareCall(sql);            
            cs.setArray(1,conn.createARRAY("MSG_ARRAY",empnos.toArray()));
            return cs;
        }
    },
    new CallableStatementCallback<Object>() {

        @Override
        public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
            cs.execute();
            return null;
        }
    });
}

这样执行则能成功:

image.png

0条评论

点击登录参与评论