首页 > 解决方案 > oracleConnection.createARRAY 不适用于 WebLogic 数据源连接

问题描述

所以,我使用的是在 Spring 中定义的数据源,它工作正常。然后我更新了我的项目以从运行应用程序的 Weblogic 服务器获取数据源。这也适用于大多数对数据库的调用,除了一个场景 - 此场景涉及将对象列表发送到数据库,基于使用 Structs 在 Java 中定义的数据库类型。

完整的方法是:

@Override
public List<String> saveAllocation(String originalId, List<Parcel> parcels) throws SQLException {

    if(originalId == null || parcels == null) {
        return null;
    }

    List<String> results = null;

    String result = null;
    String log = null;

    OracleConnection oracleConnection = (OracleConnection)jdbcTemplate.getDataSource().getConnection();

        try {

            OracleCallableStatement cs = (OracleCallableStatement) oracleConnection.prepareCall("{ call PACKAGE.Update(?, ?, ?, ?) }");

            Struct[] cpoList = new Struct[parcels.size()];

            for(int i = 0; i < parcels.size(); i++) {
                Object[] obj = new Object[] { parcels.get(i).getParcel_id(), parcels.get(i).getPublicID().toUpperCase() };
                Struct struct = oracleConnection.createStruct("SCHEME_NAME.PARCEL_OBJ", obj);
                cpoList[i] = struct;
            }

            Array array = oracleConnection.createARRAY("SCHEME_NAME.PARCEL_TAB", cpoList);


            cs.setString(1, originalId);
            cs.setArray(2, array);
            cs.registerOutParameter(3, Types.VARCHAR);
            cs.registerOutParameter(4, Types.VARCHAR);

            cs.executeUpdate();

            log = cs.getObject(3).toString();
            result = cs.getObject(4).toString();


            results = new ArrayList<>();

            results.add(result);
            results.add(log);

        } catch(SQLException e) {
            //Log exception
            return results;
        } catch(Exception e) {
            //Log exception
            return results;

        } finally {

            if (cs != null) {
                cs.close();
            }
        }

        return results;

    }
}

数据库对象定义为:

PARCEL_OBJ

create or replace TYPE parcel_obj AS OBJECT (PARCEL_ID VARCHAR2(11), PUBLIC_ID VARCHAR2(20));

PARCEL_TAB

create or replace TYPE parcel_tab IS TABLE OF parcel_obj;

申请失败上线

Array array = oracleConnection.createARRAY("SCHEME_NAME.PARCEL_TAB", cpoList);

异常消息是:

java.sql.SQLException: Fail to convert to internal representation: weblogic.jdbc.wrapper.Struct_oracle_sql_STRUCT@187>

我的 JNDI 连接在我的 application.properties 中定义,例如:

spring.datasource.jndi-name=jdbc/pio

任何帮助,将不胜感激!

标签: javaoraclestructweblogicjndi

解决方案


正如文档所述。

默认情况下,Array、Blob、Clob、NClob、Ref、SQLXML 和 Struct 的数据类型对象以及 ParameterMetaData 和 ResultSetMetaData 对象使用 WebLogic 包装器进行包装。

在某些情况下,将 wrapping 参数设置为 false 可以显着提高性能并允许应用程序使用本机驱动程序。

我没有看到禁用该选项的问题,因为它struct在首先调用对象时会导致问题。


推荐阅读