和isEmpty / isNull

时间:2019-04-23 06:25:59

标签: spring-boot criteria-api

我有一些具有能力(例如驾驶执照等)的工人,然后有些机制需要某些能力。有时,这些机制根本不需要能力。

目前,我有一个带有in子句的规范,该规范可以正常工作,但我希望它也可以发出不需要任何能力即可运行的机制。

public static Specification<Mechanism> hasCompetences(String searchTerm) {
        return (root, query, criteriaBuilder) -> {
            query.distinct(true);
            List<String> list = new ArrayList<>(Arrays.asList(searchTerm.split(",")));
            return root.join("competences").get("name").in(list);
        };
    }

如果我有3种具有类似能力的机制

汽车| B类|

范| C类别|

自行车|(此处无数据)|

在请求mechanisms?competences=B-Category之后,它会按预期返回Car,但是我也想获得Bicycle。

或者有没有办法获得所有不需要能力的机制?我尝试了mechanisms?competences=,但返回了[]

编辑:

这是我现在所在的位置:

public static Specification<Mechanism> hasCompetences(List<String> list) {
        return (root, query, cb) -> {
            query.distinct(true);
            return cb.or(
                    cb.isEmpty(root.join("competences")),
                    root.join("competences").get("name").in(list)
            );
        };
    }

但是isEmpty给我这个错误:

java.lang.IllegalArgumentException: unknown collection expression type [org.hibernate.query.criteria.internal.path.SetAttributeJoin]

Edit2:

public static Specification<Mechanism> hasCompetences(List<String> list) {
        return (root, query, cb) -> {
            query.distinct(true);
            Join<Mechanism, Set<Competence>> competences = root.join("competences", JoinType.LEFT);
            return cb.or(
                    root.join("competences").get("name").in(list),
                    cb.isEmpty(competences)
            );
        };
    }

错误:

unknown collection expression type [org.hibernate.query.criteria.internal.path.SetAttributeJoin];

1 个答案:

答案 0 :(得分:1)

您有2个错误:

  1. 匹配空集合的条件是cb.isEmpty(root.get("competences"))
  2. 您需要指定左连接。 root.join("competences", JoinType.LEFT)

没有第二个修订,您将进行内部联接,因此您将永远不会检索具有空缺权限的机制。

更新

您提出了

Join<Mechanism, Set<Competence>> competences = root.join("competences", JoinType.LEFT);
return cb.or(
    root.join("competences").get("name").in(list),
    cb.isEmpty(competences)
);

isEmptySetAttributeJoinroot.join的结果)上不起作用-上面的第1点。

尝试

Join<Mechanism, Set<Competence>> competences = root.join("competences", JoinType.LEFT);
return cb.or(
    competences.get("name").in(list),
    cb.isEmpty(root.get("competences"))
);