HQL查询报unexpected end of subtree错误,求解决方案
问题
编写HQL查询语句获取某字段值存在于Integer类型列表中的所有对象时,出现「unexpected end of subtree」错误。
查询代码如下:
@Query( value = "SELECT DISTINCT sm FROM StopMatrix sm " + "JOIN FETCH sm.provider p " + "LEFT JOIN FETCH sm.authorizedStopCollection aus " + "LEFT JOIN FETCH aus.cstopStart cs " + "LEFT JOIN FETCH aus.cstopEnd ce " + "WHERE p.proCode IN (:allowedProviderCodes)" ) List<StopMatrix> findAllByAllowedProviderCodes(@Param("allowedProviderCodes") List<Integer> readAllowedProviderCodes);
报错信息:
org.hibernate.hql.ast.QuerySyntaxException: unexpected end of subtree [SELECT DISTINCT sm FROM com.parkeon.transfolio.fares.jpa.matrix.StopMatrix sm JOIN FETCH sm.provider p LEFT JOIN FETCH sm.authorizedStopCollection aus LEFT JOIN FETCH aus.cstopStart cs LEFT JOIN FETCH aus.cstopEnd ce WHERE p.proCode IN ()]
解决方法
从报错信息能看到,问题根源是传入的allowedProviderCodes是空列表,导致HQL生成了非法的IN()语法,这是Hibernate处理空集合时的常见问题,以下是几种解决方式:
提前校验列表非空
在调用查询方法前,先判断传入的列表是否为空。如果是空列表,直接返回空结果,避免执行无效查询:public List<StopMatrix> getStopMatrices(List<Integer> providerCodes) { if (providerCodes == null || providerCodes.isEmpty()) { return Collections.emptyList(); } return stopMatrixRepository.findAllByAllowedProviderCodes(providerCodes); }修改HQL兼容空列表场景
在WHERE条件中增加空集合判断,通过OR逻辑处理空列表的情况:@Query( value = "SELECT DISTINCT sm FROM StopMatrix sm " + "JOIN FETCH sm.provider p " + "LEFT JOIN FETCH sm.authorizedStopCollection aus " + "LEFT JOIN FETCH aus.cstopStart cs " + "LEFT JOIN FETCH aus.cstopEnd ce " + "WHERE (:allowedProviderCodes IS EMPTY OR p.proCode IN (:allowedProviderCodes))" ) List<StopMatrix> findAllByAllowedProviderCodes(@Param("allowedProviderCodes") List<Integer> readAllowedProviderCodes);注:这种写法会在列表为空时返回所有符合关联条件的
StopMatrix记录,如果需要空列表时返回空结果,优先选择第一种方法。利用Spring Data JPA自动生成查询(简化场景)
如果不需要复杂的FETCH JOIN来避免N+1查询,可以直接用Spring Data JPA的命名查询,它会自动处理空列表:List<StopMatrix> findDistinctByProvider_ProCodeIn(List<Integer> allowedProviderCodes);
内容的提问来源于stack exchange,提问作者Yacine Ouahmad
相关产品推荐
相关产品推荐

