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

Spring JPA @Query结合Specification与参数时抛可选参数异常

JPA联合分页、Specification与自定义参数查询报错解决

问题场景

编写JPA复杂查询时,需要同时实现分页、Specification过滤和额外自定义参数的协同工作,定义了如下Repository方法:

@Query(value = QRY_DATA, countQuery = QRY_DATA_COUNT)
Page<NotificationUserSettingsPageResponse> findAllFrontend(@Nullable Specification<NotificationUserSettings> spec, Pageable pageable, @Param("user_UUID") String userUUID);

执行该方法时触发报错:

but parameter 'Optional[spec]' not found in annotated query

移除最后一个userUUID参数后方法可正常运行,但添加该参数后,JPA会错误地将Specification当作查询参数去匹配注解SQL中的占位符。需要说明的是,user_UUID参数用于关联查询的ON子句中,无法移入Specification内处理,具体查询语句如下:

SELECT new pl.notification.dto.response.NotificationUserSettingsPageResponse(s.id,
s.userUUID, n.id,
n.system, n.name, n.category,
b.id, b.businessRule, 
CASE WHEN s.id > 0 
THEN s.isEmail ELSE 'T' END AS is_email,
CASE WHEN s.id > 0 
THEN s.isSMS ELSE 'T' END AS is_sms,
CASE WHEN s.id > 0 
THEN s.isPortal ELSE 'T' END AS is_portal)
FROM BusinessRuleConfig b
RIGHT JOIN NotificationConfig n on n.id = b.notificationConfig.id
LEFT JOIN NotificationUserSettings s on s.id = n.id AND s.id = b.id AND s.userUUID =:user_UUID 

解决方案

问题核心是Spring Data JPA对混合使用@Query注解和Specification的参数顺序有严格要求:当同时使用Specification和自定义@Param参数时,必须把Specification放在所有自定义参数的后面,否则JPA会错误解析参数类型。

修改后的Repository方法如下:

@Query(value = QRY_DATA, countQuery = QRY_DATA_COUNT)
Page<NotificationUserSettingsPageResponse> findAllFrontend(Pageable pageable, @Param("user_UUID") String userUUID, @Nullable Specification<NotificationUserSettings> spec);

补充说明

  1. 同步修改分页总数查询语句(QRY_DATA_COUNT),确保里面也包含:user_UUID占位符,否则分页总数计算会报错。示例count查询:
SELECT COUNT(DISTINCT n.id)
FROM BusinessRuleConfig b
RIGHT JOIN NotificationConfig n on n.id = b.notificationConfig.id
LEFT JOIN NotificationUserSettings s on s.id = n.id AND s.id = b.id AND s.userUUID =:user_UUID
  1. Specification作为动态查询条件的载体,必须处于参数列表末尾,这样JPA才能正确识别它是用于拼接动态查询的特殊参数,而非普通SQL占位符参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:40:27