Спецификация ИЛИ предложение, в и isEmpty / isNull - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть работники, обладающие компетенциями (водительские права и т. Д.), А также существуют механизмы, требующие определенных компетенций. Иногда механизмы вообще не требуют компетенций.

В настоящее время у меня есть спецификация с предложением 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 он возвращает автомобиль, как и ожидалось, но я бы тоже хотел получить велосипед.

Или есть способ получить все механизмы, которые не требуют компетенций? Я пытался mechanisms?competences=, но это вернулось [].

Edit:

Вот где я сейчас нахожусь:

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]

Edit2:

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

1 Ответ

1 голос
/ 23 апреля 2019

У вас есть 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"))
);
...