You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle JDBC执行rs.next()抛出ArrayIndexOutOfBoundsException求助

Oracle 11.2 查询ALL_OBJECTS时ResultSet.next()抛出ArrayIndexOutOfBoundsException 解决方法

问题背景

  • 环境:Oracle 11.2,Spring Boot 2.3.12,使用BasicDataSource连接池
  • 症状:执行查询ALL_OBJECTS的SQL时,每次调用rs.next()都会抛出ArrayIndexOutOfBoundsException,堆栈指向Oracle驱动的T4CTTIrxdsBitset.set方法
  • 已尝试:更换ojdbc8-12.2.0.1、ojdbc6-11.2.0.3、ojdbc8-19等驱动版本,设置Statement.setFetchSize(),均未解决问题

核心原因

该错误本质是Oracle驱动与数据库版本不兼容导致的解析异常:高版本驱动(如ojdbc8、ojdbc19)针对Oracle 12c+的特性做了逻辑优化,连接低版本Oracle 11.2时,处理结果集的位向量(BitVector)解析会出现索引越界;加上ALL_OBJECTS是包含大量字段的系统视图,驱动解析全量字段时更容易触发该bug。

解决方案

1. 严格匹配驱动与Oracle版本

Oracle 11.2必须使用对应版本的稳定驱动,推荐使用ojdbc6-11.2.0.4.jar(官方适配11.2的最优版本),禁止使用适配12c+的ojdbc8或19c+的ojdbc19。

2. 避免SELECT *,明确指定所需字段

ALL_OBJECTS包含数十个字段,SELECT *会让驱动处理大量不必要的元数据,大幅增加触发bug的概率。修改SQL为仅查询业务需要的字段:

String sql = "SELECT OWNER, OBJECT_NAME, OBJECT_TYPE, LAST_DDL_TIME FROM ALL_OBJECTS O WHERE O.OWNER = 'LINEWELL' AND O.OBJECT_TYPE IN ('TABLE', 'VIEW')";

3. 指定结果集类型为向前只读

默认创建的Statement可能生成可滚动结果集(InsensitiveScrollableResultset),其复杂的处理逻辑更容易触发异常。创建Statement时显式指定结果集类型:

Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);

4. 优化连接池与驱动配置

在BasicDataSource中添加驱动属性,优化结果集读取逻辑:

datasource.addConnectionProperty("oracle.jdbc.defaultRowPrefetch", "100");
datasource.addConnectionProperty("oracle.jdbc.useFetchSizeWithLongColumn", "true");

修改后的完整代码示例

public void demo() {
    List<Map<String, String>> resultList = new ArrayList<>();
    // 仅查询所需字段
    String sql = "SELECT OWNER, OBJECT_NAME, OBJECT_TYPE, LAST_DDL_TIME FROM ALL_OBJECTS O WHERE O.OWNER = 'LINEWELL' AND O.OBJECT_TYPE IN ('TABLE', 'VIEW')";
    BasicDataSource datasource; // 已初始化的数据源
    try (
            Connection con = datasource.getConnection();
            // 指定向前只读的结果集类型
            Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
            ResultSet rs = stmt.executeQuery(sql)
    ) {
        stmt.setFetchSize(100); // 设置合理的批量读取大小
        while (rs.next()) {
            Map<String, String> map = new HashMap<>();
            map.put("TableCatalog", rs.getString("OWNER"));
            map.put("TableSchema", rs.getString("OWNER"));
            map.put("TableName", rs.getString("OBJECT_NAME"));
            map.put("TableType", rs.getString("OBJECT_TYPE"));
            map.put("LastModifyTime", rs.getString("LAST_DDL_TIME"));
            resultList.add(map);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println(resultList.size());
}

额外排查方向

如果上述方法无效,可尝试:

  • 升级Spring Boot 2.3.x到最新补丁版本,或升级到2.4+(注意兼容性)
  • 检查Oracle 11.2是否安装了最新CPU补丁,部分旧版本存在驱动交互bug

内容的提问来源于stack exchange,提问作者great-jin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 14:57:49