首页 > 解决方案 > 规范 OR 子句,在 isEmpty/isNull 中

问题描述

我的员工有能力(驾驶执照等),还有一些机制需要一定的能力。有时,这些机制根本不需要能力。

目前,我有一个带有 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 后,但我也想得到自行车。

或者有没有办法获得所有不需要能力的机制?我试过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]

编辑2:

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];

标签: spring-bootcriteria-api

解决方案


您有 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)
);

isEmpty不起作用SetAttributeJoin(的结果root.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"))
);

推荐阅读