Как инициализировать спецификацию Spring Data JPA? - PullRequest
0 голосов
/ 25 июня 2018

У меня есть метод, который выполняет поиск с фильтрами, поэтому я использую Спецификацию для построения динамического запроса:

public Page<Foo> searchFoo(@NotNull Foo probe, @NotNull Pageable pageable) {

        Specification<Foo> spec = Specification.where(null);  // is this ok?

        if(probe.getName() != null) {
            spec.and(FooSpecs.containsName(probe.getName()));
        }
        if(probe.getState() != null) {
            spec.and(FooSpecs.hasState(probe.getState()));
        }
        //and so on...

        return fooRepo.findAll(spec, pageable);
}

Существует вероятность того, что фильтры не указаны, поэтому я бы перечислил все без фильтрации. Имея это в виду, как я должен инициализировать spec? Прямо сейчас приведенный выше код не работает, поскольку он всегда возвращает мне один и тот же результат: все регистры таблицы, фильтрация не применена, хотя and были выполнены операции.

FooSpecs:

public class PrescriptionSpecs {

    public static Specification<Prescription> containsCode(String code) {
        return (root, criteriaQuery, criteriaBuilder) ->
            criteriaBuilder.like(root.get(Prescription_.code), "%" + code + "%");
    }

    // some methods matching objects...
    public static Specification<Prescription> hasContractor(Contractor contractor) {
        return (root, criteriaQuery, criteriaBuilder) ->
            criteriaBuilder.equal(root.get(Prescription_.contractor), contractor);
    }
    //... also some methods that access nested objects, not sure about this
    public static Specification<Prescription> containsUserCode(String userCode) {
        return (root, criteriaQuery, criteriaBuilder) ->
            criteriaBuilder.like(root.get(Prescription_.user).get(User_.code), "%" + userCode + "%");
    }
}

1 Ответ

0 голосов
/ 25 июня 2018

Specification.where(null) работает просто отлично. Он помечен @Nullable, а реализация обрабатывает null значения, как и должно быть.

Проблема в том, что вы используете метод and, как если бы он изменил Specification, но он создает новый. Поэтому вы должны использовать

spec = spec.and( ... );
...