JPA 规范和 .where 子句中的空参数
JPA Specification and null parameter in .where clause
我写了两个规范,如果它们的参数为 null,return null。
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
returns null
,我在解析 where
子句时从 checkPackageAccess
得到一个 nullPointerException
。
- 如果
ByIng
returns null
,它就会被忽略(就像它应该被忽略的那样)并且查询只匹配另一个谓词。
- 如果我切换两个谓词,将
ByIng
作为第一个,然后将 ByLinea
放在 where
子句中,则所有组合都有效。
最好避免从方法返回 null
。
您可以使用criteriaBuilder
.conjunction() to ignore null
parameter Specification
. It generates always true
Predicate
. There is an opposite method 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 + "%");
}
}
P.S。如果第一个 Specification
是 null
试图访问一个方法 and
,你会得到 NullPointerException
。
要清楚它看起来像这样
Specification.where(null.and(getProdottoByIngSpec(ing)));
但是如果只有第二个 Specification
是 null
这个有效
Specification.where(getProdottoByLineaSpec(linea).and(null));
因为and方法参数可以是null
我写了两个规范,如果它们的参数为 null,return null。
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
returnsnull
,我在解析where
子句时从checkPackageAccess
得到一个nullPointerException
。 - 如果
ByIng
returnsnull
,它就会被忽略(就像它应该被忽略的那样)并且查询只匹配另一个谓词。 - 如果我切换两个谓词,将
ByIng
作为第一个,然后将ByLinea
放在where
子句中,则所有组合都有效。
最好避免从方法返回 null
。
您可以使用criteriaBuilder
.conjunction() to ignore null
parameter Specification
. It generates always true
Predicate
. There is an opposite method 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 + "%");
}
}
P.S。如果第一个 Specification
是 null
试图访问一个方法 and
,你会得到 NullPointerException
。
要清楚它看起来像这样
Specification.where(null.and(getProdottoByIngSpec(ing)));
但是如果只有第二个 Specification
是 null
这个有效
Specification.where(getProdottoByLineaSpec(linea).and(null));
因为and方法参数可以是null