Сравните две коллекции на равенство в API критериев JPA - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть следующие сущности в 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())
    );
  }

В моем решении есть две проблемы:

  1. Я думаю, что он действительно работает только с Set - он не работает, если используется List и там есть дубликаты элементов.
  2. Решение громоздко - держу пари, чтобыть более простым и чистым решением.
...