使用JPA标准和JsonBinaryType

问题描述

我有一个JPA / Hibernate实体,该实体具有一个JSONB列(使用https://github.com/vladmihalcea/hibernate-types)来存储字符串列表。到目前为止,一切正常。

@TypeDef(name = "jsonb",typeClass = JsonBinaryType.class)
@Type(type = "jsonb")
@Column(name = "TAGS",columnDeFinition = "jsonb")
private List<String> tags;

现在我要检查字符串列表中是否包含另一个字符串。

可以通过编写本机查询并使用Postgres的@>运算符来做到这一点。由于其他原因(查询更为复杂),我不想朝这个方向发展。我目前的方法是在Spring Data规范(since the operator is just alias to this function)中调用jsonb_contains方法,例如jsonb_contains('["tag1","tag2","tag3"]','["tag1"]')。我正在努力的是使第二个参数正确。

我最初的方法是也使用字符串列表。

    public static Specification<MyEntity> hasTag(String tag) {
        return (root,query,cb) -> {
            if (StringUtils.isEmpty(tag)) {
                return criteriaBuilder.conjunction();
            }
            Expression<Boolean> expression = criteriaBuilder.function("jsonb_contains",Boolean.class,root.get("tags"),criteriaBuilder.literal(List.of(tag)));
            return criteriaBuilder.isTrue(expression);
        };
    }

这将导致以下错误

Caused by: org.postgresql.util.PsqlException: ERROR: function jsonb_contains(jsonb,character varying) does not exist
  Hinweis: No function matches the given name and argument types. You might need to add explicit type casts.
  Position: 375

它确实知道root.get("tags")被映射到JSONB,但是对于第二个参数却没有。我该如何正确处理?真的有可能吗?

解决方法

我认为原因是您将 varchar 作为第二个参数传递。 jsonb_contains() 需要两个 jsonb 参数。

要检查 jsonb 数组是否包含字符串数组中的所有/任何值,您需要使用其他运算符:?&?|

它们在 PSQL 9.4 中的方法绑定分别是:jsonb_exists_alljsonb_exists_any

在您的 PSQL 版本中,您可以通过以下命令进行检查:

select * from pg_operator where oprname = '?&'