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

将PostgreSQL JSONB查询转为Spring JPA原生查询遇参数传递问题

Spring JPA原生查询传递JSON数组参数问题

问题场景

原PostgreSQL查询可正常匹配jsonb列中包含指定引用项的数据:

SELECT * FROM references 
WHERE json_data -> 'References' @> 
any(cast(ARRAY['[{"Id": "001", "Type": "Type-1"}]', '[{"Id": "004", "Type": "Type-4"}]'] as jsonb[]))

对应的jsonb列数据结构:

{
    "CorrelationId": "1234-123-123",
    "References": [
        {
            "Id": "001",
            "Type": "Type-1"
        },
        {
            "Id": "002",
            "Type": "Type-2"
        },
        {
            "Id": "003",
            "Type": "Type-3"
        }
    ]
}

但转换为Spring JPA原生查询后无法正常工作:

@Query(
    value = """
    SELECT * FROM references 
    WHERE json_data -> 'References' @> 
    any(cast(ARRAY[:ids] as jsonb[]))
    """,
    nativeQuery = true
)
fun findAllByReferences(@Param("ids") ids: List<String>)

调用代码:

repository.findAllByReferences("[{\"Id\": \"001\", \"Type\": \"Type-1\"}]", "[{\"Id\": \"004\", \"Type\": \"Type-4\"}]")

问题原因

直接使用ARRAY[:ids]时,Spring JPA无法正确将List<String>转换为PostgreSQL的字符串数组,后续的jsonb[]类型转换会出现参数绑定错误。

解决方案

方案1:直接传递数组参数并转换类型

修改查询方法,使用Array<String>接收参数,直接通过::jsonb[]完成类型转换:

@Query(
    value = """
    SELECT * FROM references 
    WHERE json_data -> 'References' @> ANY(:ids::jsonb[])
    """,
    nativeQuery = true
)
fun findAllByReferences(@Param("ids") ids: Array<String>)

调用示例:

val targetReferences = arrayOf(
    """[{"Id": "001", "Type": "Type-1"}]""",
    """[{"Id": "004", "Type": "Type-4"}]"""
)
repository.findAllByReferences(targetReferences)

方案2:使用jsonb_build_array构造JSON数组

如果偏好使用List<String>或可变参数,可借助PostgreSQL的jsonb_build_array函数构造数组:

@Query(
    value = """
    SELECT * FROM references 
    WHERE json_data -> 'References' @> ANY(jsonb_build_array(:ids)::jsonb[])
    """,
    nativeQuery = true
)
fun findAllByReferences(@Param("ids") ids: List<String>)

或使用可变参数简化调用:

@Query(
    value = """
    SELECT * FROM references 
    WHERE json_data -> 'References' @> ANY(jsonb_build_array(?1, ?2)::jsonb[])
    """,
    nativeQuery = true
)
fun findAllByReferences(vararg ids: String)

调用示例:

repository.findAllByReferences(
    """[{"Id": "001", "Type": "Type-1"}]""",
    """[{"Id": "004", "Type": "Type-4"}]"""
)

注意事项

  • 确保传入的每个字符串都是合法的JSON数组格式(比如[{"Id": "001", "Type": "Type-1"}]),而非单个对象的JSON字符串,否则@>包含运算符无法匹配。
  • 若使用Kotlin,字符串中的双引号可通过三重引号(""")避免转义,提升可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:54:53