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

Spring Data JPA执行PostgreSQL JSONB查询报错:操作符不存在

解决Spring Data JPA原生查询中PostgreSQL jsonb @>操作符类型不匹配报错

在PGAdmin中执行包含jsonb @>操作符的查询可以正常运行,但使用Spring Data JPA原生查询时,无论传入List<String>还是JSON格式字符串,都会抛出如下异常:

ERROR: operator does not exist: jsonb @> character varying
  Hint: No operator matches the given name and argument types. You might need to add explicit type casts

问题原因

PostgreSQL的@>(jsonb包含)操作符要求左右两边的操作数均为jsonb类型,但Spring Data JPA默认会将:

  • List<String>参数转换为SQL数组类型(而非jsonb数组)
  • JSON格式字符串参数转换为varchar类型

类型不匹配直接触发了上述报错。

解决方案

根据传入参数的类型,有两种可行的修改方式:

1. 传入JSON格式字符串时:显式转换参数为jsonb

直接在查询语句中用PostgreSQL的::jsonb语法对参数进行类型强制转换:

修改后的原生查询代码:

@Query(value = "select org.* from organic org " +
        "where (org.data ->> 'bfId') = :bfId " +
        "and ((org.data -> 'attributes') ->> 'orgType') = :orgType " +
        "and (org.data ->> 'instId') = :instId " +
        "and (org.data -> 'accs') @> :accsIds::jsonb " +
        "and ((org.data -> 'attributes') -> 'reg') @> :reg::jsonb " +
        "and ((org.data -> 'attributes') -> 'desk') @> :desk::jsonb " +
        "and ((org.data -> 'attributes') -> 'country') @> :countaries::jsonb", nativeQuery = true)
List<Organic> getData(String bfId, String orgType, String instId, 
                      String accsIds, String reg, String desk, String countaries);

调用时传入标准JSON数组字符串(如"[\"accs_id1\"]")即可。

2. 传入List时:将SQL数组转换为jsonb数组

Spring会把List<String>转为SQL数组,我们可以用PostgreSQL的array_to_json()函数将其转为JSON数组,再强制转为jsonb:

修改后的原生查询代码:

@Query(value = "select org.* from organic org " +
        "where (org.data ->> 'bfId') = :bfId " +
        "and ((org.data -> 'attributes') ->> 'orgType') = :orgType " +
        "and (org.data ->> 'instId') = :instId " +
        "and (org.data -> 'accs') @> array_to_json(:accsIds)::jsonb " +
        "and ((org.data -> 'attributes') -> 'reg') @> array_to_json(:reg)::jsonb " +
        "and ((org.data -> 'attributes') -> 'desk') @> array_to_json(:desk)::jsonb " +
        "and ((org.data -> 'attributes') -> 'country') @> array_to_json(:countaries)::jsonb", nativeQuery = true)
List<Organic> getData(String bfId, String orgType, String instId, 
                      List<String> accsIds, List<String> reg, List<String> desk, List<String> countaries);

这种方式可以直接传入List<String>(如Arrays.asList("accs_id1")),无需手动拼接JSON字符串。

备选方案:使用jsonb_contains函数

也可以用PostgreSQL内置的jsonb_contains函数替代@>操作符,语义更清晰,同样需要保证参数为jsonb类型:

@Query(value = "select org.* from organic org " +
        "where (org.data ->> 'bfId') = :bfId " +
        "and ((org.data -> 'attributes') ->> 'orgType') = :orgType " +
        "and (org.data ->> 'instId') = :instId " +
        "and jsonb_contains(org.data -> 'accs', array_to_json(:accsIds)::jsonb) " +
        "and jsonb_contains((org.data -> 'attributes') -> 'reg', array_to_json(:reg)::jsonb) " +
        "and jsonb_contains((org.data -> 'attributes') -> 'desk', array_to_json(:desk)::jsonb) " +
        "and jsonb_contains((org.data -> 'attributes') -> 'country', array_to_json(:countaries)::jsonb)", nativeQuery = true)
List<Organic> getData(String bfId, String orgType, String instId, 
                      List<String> accsIds, List<String> reg, List<String> desk, List<String> countaries);

验证

修改后执行查询,Spring Data JPA会正确将参数转换为jsonb类型,匹配@>操作符的要求,即可正常返回结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:10:35