Спецификация JPA и нулевой параметр в предложении .where - PullRequest
0 голосов
/ 31 января 2020

Я написал две спецификации, которые возвращают ноль, если их параметр равен нулю.

public static Specification<Prodotto> getProdottoByLineaSpec (String linea) {

        if (linea != null) {
            return (root, query, criteriaBuilder) -> {
                return criteriaBuilder.like((root.join("linea")).get("nome"), "%"+linea+"%");
            };
        }
        else return null;
    }

public static Specification<Prodotto> getProdottoByIngSpec (String ing) {

        if (ing != null) {
            return (root, query, criteriaBuilder) -> {
                return criteriaBuilder.like(((root.join("listaQuoteIng")).join("ing")).get("nome"), "%"+ing+"%");
            };
        }
        else return null;
    }

Затем я создал третью, которая объединяет предыдущие с оператором and внутри предложения where:

public static Specification<Prodotto> getProdottoByMainTraits (String linea, String ing) {

        return Specification.where(getProdottoByLineaSpec(linea).and(getProdottoByIngSpec(ing)));
    }

Это забавная часть:

  • Если ByLinea возвращает null, я получаю nullPointerException из checkPackageAccess при разрешении предложения where .
  • Если ByIng возвращает null, он просто игнорируется (как и должно быть), и запрос соответствует только другому предикату.
  • Если я переключаю два предиката, ставим ByIng как первый, а затем ByLinea внутри предложения where, все работает в каждой комбинации.

1 Ответ

1 голос
/ 01 февраля 2020

Рекомендуется избегать возврата null из методов.

Вы можете использовать criteriaBuilder. conunction () , чтобы игнорировать null параметр Specification. Он генерирует всегда true Predicate. Есть противоположный метод criteriaBuilder. disjunction ()

public static Specification<Prodotto> getProdottoByLineaSpec (String linea) {

    return (root, query, criteriaBuilder) -> {
        if (linea == null) {                 
            return criteriaBuilder.conjunction();
        }

        return criteriaBuilder.like((root.join("linea")).get("nome"), "%" + linea + "%");            
    }
}

PS Вы получаете NullPointerException, если первым Specification является null, пытающимся получить доступ к методу and. Чтобы было понятно, это выглядит так

Specification.where(null.and(getProdottoByIngSpec(ing)));

Но если только секунда Specification равна null, то эта работает

Specification.where(getProdottoByLineaSpec(linea).and(null));

, потому что и параметр метода может быть null

...