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

Spring+Hibernate+Oracle19c环境ojdbc8传空查询参数报错咨询

问题根因分析

该错误是ojdbc 19.3~19.8版本的已知缺陷,触发位置为客户端结果集缓存的空参数缓存Key计算逻辑,DynamicByteArray类的updateDigest方法对空值的边界处理异常,直接触发断言报错。
仅JUnit场景触发的原因:测试环境通常会默认开启JDBC语句隐式缓存来提升单测执行效率,而生产环境未开启该配置,不会触发缓存逻辑因此不会报错。

解决方案

按优先级从高到低排列:

  • 方案1:升级ojdbc驱动版本
    直接将ojdbc8驱动升级到19.11.0.0及以上版本即可,该缺陷在高版本中已被Oracle官方修复,无需修改任何业务代码和配置。
  • 方案2:禁用Oracle JDBC隐式语句缓存
    无需升级驱动,在JDBC连接配置中添加参数即可生效:
    如果你使用Spring配置,在数据源的连接属性中添加以下配置(以SpringBoot+Hikari连接池为例):
    spring:
      datasource:
        hikari:
          data-source-properties:
            oracle.jdbc.implicitStatementCacheSize: 0
    
    单测场景也可以直接在测试的JVM启动参数中添加-Doracle.jdbc.implicitStatementCacheSize=0。
  • 方案3:代码层规避
    如果你暂时无法修改驱动和配置,可以调整查询逻辑规避空参数场景:
    // 原生查询示例
    @Override
    public BigDecimal testQueryNativeEmpty(String empty) {
        // 空参数直接返回符合业务逻辑的默认值,跳过空参数查询
        if (empty == null || empty.isEmpty()) {
            return BigDecimal.ZERO;
        }
        StringBuilder queryString = new StringBuilder("SELECT count(1) from silab.system_param sp ");
        queryString.append("where sp.spm_code = :empty ");
        Query query = entitymanager.createNativeQuery(queryString.toString());
        query.setParameter("empty", empty);
        return (BigDecimal) query.getSingleResult();
    }
    
    也可以调整查询语句使用NVL函数统一处理空值,避免传入空参数触发缓存缺陷:
    SELECT count(1) from silab.system_param sp where nvl(sp.spm_code, ' ') = nvl(:empty, ' ')
    

内容的提问来源于stack exchange,提问作者Martel Benjamin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:27:02