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

Spring JPA原生查询PostgreSQL JSONB字段参数混合报错排查

Spring JPA原生查询PostgreSQL jsonb字段报错解决

问题场景

要通过Spring JPA原生查询筛选PostgreSQL数据库中,jsonb类型字段severity_map包含指定键的数据。原始SQL语句如下:

select * FROM targeted_event_catalog e WHERE e.severity_map ? 'serviceName';

对应的Spring JPA代码实现:

@Query(value = "SELECT * FROM targeted_event_catalog e WHERE e.severity_map ? :service", nativeQuery = true)
List<TargetedEventRegistration> findByService(@Param("service") String service);

执行时抛出错误:

Caused by: java.lang.IllegalArgumentException: Mixing of ? parameters and other forms like ?1 is not supported

severity_map字段的数据示例:

{"serviceName": ["info", "warning", "critical"]}

尝试使用??替代?后仍未解决问题。

错误原因

PostgreSQL中?是jsonb类型的键存在性检查运算符,但在Spring JPA的原生查询解析逻辑中,?会被识别为参数占位符。此时SQL中同时存在运算符?和命名参数:service,导致参数解析逻辑混乱,触发了参数混合使用的异常。

解决方法

方案1:使用PostgreSQL内置函数替代运算符

直接使用PostgreSQL提供的jsonb_exists函数检查jsonb字段是否包含指定键,避免和Spring的参数占位符冲突:

@Query(value = "SELECT * FROM targeted_event_catalog e WHERE jsonb_exists(e.severity_map, :service)", nativeQuery = true)
List<TargetedEventRegistration> findByService(@Param("service") String service);

方案2:转义运算符并使用位置参数

如果要保留?运算符,需要用??进行转义,同时改用位置参数(不能混合命名参数):

@Query(value = "SELECT * FROM targeted_event_catalog e WHERE e.severity_map ?? ?1", nativeQuery = true)
List<TargetedEventRegistration> findByService(String service);

这里第一个?用于转义PostgreSQL的运算符,第二个?1是Spring的位置参数占位符,对应方法的第一个入参。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:26:00