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

Spring Data JPA @Query新增SUPER_ADMIN后报Ordinal parameter not bound : 3错误

错误原因

该错误是参数类型混用导致的:

  • 你的@Query中同时使用了:fieldOne、:fieldTwo格式的命名参数,以及?#{}格式的Spring Security SpEL表达式。
  • 每一个?#{}表达式块都会被Spring Data JPA解析为按出现顺序计数的序数参数(即?1、?2、?3...),需要被显式绑定才能生效。
  • 新增SUPER_ADMIN的权限判断后,?#{}的数量从原来的3个变成了4个,打破了原有代码中序数参数和内部绑定逻辑的匹配关系,最终触发「序数参数3未绑定」的报错。

解决办法

最优方案:SpEL改为命名参数格式

将所有?#{替换为:#{,:#{}格式的SpEL会被Spring Data直接计算值注入查询,不会生成额外的参数占位符,和你已有的命名参数完全兼容,修改后代码如下:

String authorizeQuery = " and e.id in (select emp.id from Employee emp, Employee loggedIn where " +
        " 1 = :#{hasAuthority('ADMIN') ? 1: 0} or 1 = :#{hasAuthority('OPERATOR') ? 1: 0} or 1 = :#{hasAuthority('SUPER_ADMIN') ? 1: 0} or (loggedIn.oauthUser.id = :#{principal.id} " +
        " and loggedIn.id in (emp.id, emp.lead.id, emp.team.leader.id)))";

优化方案:合并角色判断简化代码

可以直接使用Spring Security内置的hasAnyAuthority方法一次性判断多个角色,减少冗余代码的同时降低SpEL数量:

String authorizeQuery = " and e.id in (select emp.id from Employee emp, Employee loggedIn where " +
        " 1 = :#{hasAnyAuthority('ADMIN','OPERATOR','SUPER_ADMIN') ? 1: 0} or (loggedIn.oauthUser.id = :#{principal.id} " +
        " and loggedIn.id in (emp.id, emp.lead.id, emp.team.leader.id)))";

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:15:04