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

Criteria API构造查询无返回但手动执行可命中结果问题排查

问题原因

是的,你在Criteria API中添加的to_jsonb函数调用就是查询无结果的直接原因。

两者的核心差异在于PostgreSQL对两种写法的处理逻辑完全不同:

  1. 你手动执行的SQL中,直接传入带单引号的JSON格式字符串,PostgreSQL会自动将其隐式转换为JSONB类型的数组结构[{"key":"supplierProductId", "value":"123-123-12348"}],和metadata_items的JSONB数组结构匹配,因此可以正常命中jsonb_contains的匹配规则。
  2. 而你的Criteria API生成的SQL中,使用to_jsonb(?)处理传入的字符串参数:to_jsonb函数如果接收字符串类型的输入,会直接把整个字符串转换为JSONB字符串标量,也就是最终传入jsonb_contains的第二个参数是"[{\"key\":\"supplierProductId\", \"value\":\"123-123-12348\"}]"(外层带引号的JSON字符串,不是数组结构),和metadata_items的数组结构完全不匹配,自然返回空结果。

解决方案

你不需要强行添加to_jsonb函数调用,可选两种修正方式:

  • 方式1:显式指定参数的JSONB类型映射,让EclipseLink直接把字符串参数作为JSONB类型传入,不需要额外函数转换。你可以在构造literal时指定对应的JDBC类型为JSONB专属类型,或者给实体类的metadataItems字段配置正确的JSONB类型转换器。
  • 方式2:如果必须通过函数做类型转换,把to_jsonb替换为cast操作,比如将代码修改为:
Expression<Boolean> fun = cb.function("jsonb_contains",
        Boolean.class, r.get(MediaEntity_.metadataItems),
        cb.function("cast", Object.class, 
            cb.literal("[{\"key\":\"supplierProductId\", \"value\":\"123-123-12348\"}]"),
            cb.literal("jsonb")
        )
);

cast(? as jsonb)会把输入的字符串内容解析为对应的JSON结构,和你手动写SQL的效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:48:03