Spring Boot升级2.5.13后ES @Query传List参数查询无结果问题
问题定性
这是Spring Data Elasticsearch 4.2.x系列(对应Spring Boot 2.5.x配套版本)的已知Bug,并非业务代码实现问题。
2.5版本对应的Spring Data Elasticsearch重构了@Query注解的占位符替换逻辑,处理集合类型入参时存在重复转义问题:先将集合内单个元素序列化为带双引号的JSON字符串,拼接查询语句时又额外做了一次转义包装,最终terms查询里的匹配值变成了带转义符的\"123\"格式,和索引中存储的原始123数值/字符串无法精确匹配,自然返回空结果。
低改造成本解决方案
按改造成本从低到高排序,可根据项目实际情况选择:
- 方案1:升级2.5.x分支到最新安全小版本
该转义Bug在Spring Boot 2.5.15及之后的2.5.x小版本中已完成修复,直接将spring-boot-starter-parent版本升级到2.5.x分支的最新发布版即可,不需要修改任何存量业务代码,同时满足不降级、覆盖低版本安全漏洞的要求,是首选方案。 - 方案2:自定义全局Repository片段修复参数解析逻辑
若因特殊原因不能升级版本,可新增一个通用的Elasticsearch Repository基础实现类,重写@Query注解的参数替换逻辑,拦截集合类型入参时直接生成标准JSON数组格式的参数串,跳过框架自带的重复转义流程。该实现会自动对所有存量Repository生效,不需要逐个修改已有的@Query方法,改造成本极低。 - 方案3:适配新版本@Query语法规则
若只有少量相关查询,可直接调整@Query注解写法:首先修正Java字符串中JSON的双引号转义(原有写法未转义双引号本身就不符合Java语法,旧版本靠容错逻辑运行),集合参数直接使用占位符即可,不要额外加数组括号,示例代码如下:
新版本框架识别到占位符对应集合类型入参时,会自动展开为正确的JSON数组格式,不会产生多余转义。@Repository @Timed public interface EmployeeRepository extends ElasticsearchRepository <Employee, String> { @Query("{\"terms\":{\"id\": ?0}}") @Timed Page<Employee> findByEmployeeIds(List<Long> ids); }
注意事项
不要为了适配错误转义逻辑,提前把集合内的元素处理成带转义符的字符串,会给后续版本升级留下兼容隐患。
内容的提问来源于stack exchange,提问作者Naveena Lakshmi
相关产品推荐
相关产品推荐

