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

升级Spring Boot3/Hibernate6后IN子句查询失败求助

问题原因及修复方案

问题根源

  1. 基本类型参数的null判断无效:方法中active参数是boolean基本类型,无法被赋值为null,导致JPQL里的(:active is null)条件永远不成立,同时会干扰Hibernate的参数解析逻辑。
  2. List参数的解析错误:Hibernate 6对JPQL语法的校验更严格,原写法中(:operators) is null的括号会导致解析异常,集合类型参数被错误识别为单个Integer类型,触发类型转换报错。
  3. 空List的SQL语法问题:即使解决类型问题,当operators为空List时,会生成IN ()这种非法SQL语法,导致查询失败。

修复步骤

1. 修正参数类型,让null判断生效

将active参数从boolean改为Boolean包装类型,这样才能支持传入null,让对应的条件逻辑正常工作:

Page<Package> findCoincidencesWithoutItemReference(
                                        @Param("description") String description,
                                        @Param("name") String name,
                                        @Param("active") Boolean active, // 改为包装类型
                                        @Param("operators") List<Integer> operators,
                                        Pageable page);

2. 调整JPQL中operators的条件写法

去掉参数的多余括号,同时处理空List的情况,避免生成非法SQL:

@Query ("SELECT p "
    + "FROM Package p "
    + "WHERE (:description is null or lower(p.description) LIKE %:description%) "
    + "AND (:name is null or lower(p.name) LIKE %:name%) "
    + "AND (:active is null or p.active = :active) "
    + "AND (:operators is null or size(:operators) = 0 or p.operator.id IN (:operators)) ")

size(:operators) = 0用来匹配空List的场景,避免生成IN ()的非法语法;去掉(:operators)的括号后,Hibernate能正确识别集合参数。

3. (可选)代码层预处理参数

在调用该方法前,提前判断operators是否为空,为空则传入null,可以进一步简化JPQL条件:

List<Integer> operatorsParam = operators.isEmpty() ? null : operators;
packageRepository.findCoincidencesWithoutItemReference(description, name, active, operatorsParam, page);

此时JPQL的operators条件可简化为:

AND (:operators is null or p.operator.id IN (:operators))

验证效果

修改后,传入非空List时,Hibernate会正确解析IN子句的集合参数;传入null或空List时,对应条件自动跳过,不会再触发类型转换异常或SQL语法错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:33:33