Спецификация JPA - проверка значений в нескольких строках - PullRequest
0 голосов
/ 17 января 2020

У меня есть отношение один ко многим в моей базе данных, которое после присоединения выглядит следующим образом:

 Person id | Attribute id
--------------------------
     A     |      1
     A     |      2
     A     |      3

Я пытаюсь вернуть человека, если у него есть список атрибутов I ' Я передаю в качестве параметра, используя спецификацию для фильтрации с помощью JPARepository, но наличие нескольких строк для одного и того же человека доставляет мне некоторые проблемы, я не знаю, как это сделать.

Как пример некоторого кода Спецификация:

public static Specification<Person> hasAllAttributes(List<Long> attr) {

    return (root, query, cb) -> {
       Root<Attribute> rootA = query.from(Attribute.class);
        root.alias("p");
        rootA.alias("at");

        Predicate samePerson = cb.equal(root.get(Person_.ID), rootA.get(Attribute_.PERSON));

        Predicate hasAttribute = rootA.get(Attribute_.ID).in(attr);

        return cb.and(samePerson, hasAttribute);
    };
}

Это заставляет его работать как или, он возвращает Person, если у него есть один из Атрибутов, и возвращает его несколько раз, если он содержит более одного из них в списке. Так что это на самом деле не то, что я ищу, я думаю, что оно неполное, но я не знаю, как добавить это ограничение.

1 Ответ

0 голосов
/ 20 января 2020

Решено, мне просто нужно было понять подзапросы, затем использовать один для сопоставления атрибутов со списком и подсчета совпадений, чтобы проверить, что все из списка возвращены:

public static Specification<Person> hasAllAttributes(List<Long> attr) {

    return (root, query, cb) -> {

        Subquery<Long> subquery = query.subquery(Long.class);
        Root<Attribute> subRoot = subquery.from(Attribute.class);
        subquery.select(cb.count(subRoot));

        Predicate samePerson = cb.equal(root.get(Person_.ID), subRoot.get(Attribute_.PERSON));
        Predicate attributeInList = subRoot.get(Attribute_.ID).in(attr);

        subquery.where(cb.and(samePerson, attributeInList));

        return cb.equal(subquery, attr.size());
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...