У меня есть следующие сущности в 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 и там есть дубликаты элементов. - Решение громоздко - держу пари, чтобыть более простым и чистым решением.