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

JPA @Query注解使用IN子句结合ArrayList报错问题

解决JPA @Query中IN子句绑定List参数的类型转换错误

问题原因

你遇到的CoercionException是因为当categories参数为null时,Hibernate解析JPQL会尝试将null适配为IN子句所需的集合类型,进而触发类型转换失败;另外你的isFree参数是基本类型boolean,无法为null,导致对应的WHERE条件(:isFree is null OR ...)完全失效,这也是潜在问题。

修复方案

1. 修正参数类型与条件判断

首先把isFree的参数类型从boolean改为Boolean,这样它才能接收null值,让对应条件生效:

List<ParticipantGetAllEventsDto> getAll(@Param("title") String title,
                                        @Param("categories") List<Long> categories,
                                        @Param("isFree") Boolean isFree); // 改为包装类型Boolean

2. 处理List参数的null情况

针对categories的IN子句问题,有两种可靠解决方式:

方式一:使用SPEL表达式自动处理null

修改JPQL中的条件,通过SPEL表达式在参数为null时自动替换为空集合,避免类型转换错误:

@Query("SELECT new com.example.events.dto.Event.ParticipantGetAllEventsDto(e, COUNT(p)) "
    + "FROM Event e JOIN FETCH e.reservation r JOIN FETCH r.salon s "
    + "LEFT JOIN r.participants p "
    + "JOIN e.categories c "
    + "WHERE (:title is null OR e.title LIKE %:title%) AND "
    + "(:isFree is null OR ((:isFree = true AND e.cost = 0) OR (:isFree = false AND e.cost >0 ))) AND "
    + "(:#{#categories == null} OR c.id IN :#{#categories ?: T(java.util.Collections).emptyList()} ) "
    + "GROUP BY e")
方式二:在业务层处理null参数

不在JPQL中做特殊处理,而是在调用getAll方法时,将null的categories替换为空集合,同时修改JPQL条件为判断集合是否为空:

// 修改后的JPQL条件
"(:categories IS EMPTY OR c.id IN (:categories) ) "

调用方法时做参数处理:

List<Long> categoriesParam = categories != null ? categories : Collections.emptyList();
eventRepository.getAll(title, categoriesParam, isFree);

额外说明

  • 避免直接在IN子句中使用null作为集合参数,Hibernate对这种场景的解析逻辑容易触发类型转换异常;
  • 基本类型(如boolean)无法为null,如果需要支持"不传入该参数"的查询场景,必须使用对应的包装类型(如Boolean)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:27:16