我在JPA中具有以下实体:
class Category {
Long id;
String name;
}
class Post {
Long id;
@ManyToMany
Set<Category> categories;
}
我想创建一个标准API谓词,该谓词将过滤与传递的集合中的类别完全相同的Post
个实体。
我想出了以下解决方案-检查是否存在所有传递的集合成员,然后检查两个集合的计数是否匹配:
public Predicate toPredicate(
Root<PostJpa> root,CriteriaBuilder cb,Collection<Category> categories) {
Expression<Set<Category>> categoriesExpression = root.get(Post_.categories);
Predicate categoriesPredicate = categories.stream()
.map(category -> cb.isMember(category,categoriesExpression))
.reduce(cb.and(),cb::and);
return cb.and(
categoriesPredicate,cb.equal(cb.size(categoriesExpression),categories.size())
);
}
我的解决方案有两个问题:
- 我认为它仅适用于
Set
-如果使用List并且其中存在重复的元素,则它不起作用。 - 解决方案很麻烦-我敢打赌可能会有一个更简单,更干净的解决方案。