2017-06-05 43 views
0

我有一个如下所示的Spring JPA搜索条件。哪些区域是整数。如何在Spring JPA标准没有指定值时避免NPE

cb.between(root.get(Property_.area), searchConstraint.getAreaMin(), searchConstraint.getAreaMax()) 

问题是,当用户没有在搜索中指定上界或下界时,该值为空,这导致NPE。我想到的一件事就是做一个if检查空值,如果值为null,将值设置为Integer.MAX_VAL。这样我可以避免NPE,但它也会创建很多if其他检查。所以我想知道是否有更好的方法。

+0

在我看来,你应该永远不会从这些方法返回null,但默认代替。因此,如果它是一个列表,那么返回'Collections.EMPTY_LIST',如果它是int,则取决于上下文中的“0”或“Integer.MIN_VALUE”等。检出NullObject模式:https://en.wikipedia.org/wiki/Null_Object_pattern。也许考虑使用'Optionals'。 – Shadov

回答

1

两个清洁解决方案,来我的脑海:

  • 使用选配例如`Optional.ofNullable(searchConstraint.getAreaMax())。orElse(Integer.MAX_VALUE)
  • areaMin和areaMax应该有合理的默认值,只有在用户提供了一些数据时才会覆盖它们;数据本身应该被验证
+0

谢谢大家的宝贵意见。最后一个Optional.ofNullable(searchConstraint.getAreaMax())。orElse(Integer.MAX_VALUE)最适合我。再次感谢。 – Imran

1

如果getAreaMin和getAreaMax为NULL,您可以避免/忽略添加此条件。 如果getAreaMin为NULL并且getAreaMax为NOT NULL,则可以使用le()而不是之间的方法,并且getAreaMax与gt()方法相同; 'if'代码没问题。

是这样的:

if(isNotNull(searchConstraint.getAreaMin()) && isNotNull(searchConstraint.getAreaMax())) { 
     cb.between(root.get(Property_.area), searchConstraint.getAreaMin(), searchConstraint.getAreaMax()) 
}else{ 
    if(isNotNull(searchConstraint.getAreaMin()){ 
      cb.gt(root.get(Property_.area), searchConstraint.getAreaMin()); 
    }else{ 
      cb.le(root.get(Property_.area), searchConstraint.getAreaMax()); 
    } 
} 

或者你可以创建一个像一个实用程序方法(但上一个变种是更好的DUT性能问题):

private Integer getValueOrDefault(Integer value , Integer defaultValue){ 
    return value==null ? defaultValue : value; 
} 

执行: cb.between( root.get(Property_.area),getValueOrDefault(searchConstraint.getAreaMin(),Integer.MIN_VALUE),getValueOrDefault(searchConstraint.getAreaMax(),Integer.MAX_VALUE))

1

如果两个值都可以为空,我建议将between查询拆分为两个谓词,然后将它们合并。这样,您还可以处理时,其中两个是空的情况下:

List<Predicate> predicates = new ArrayList<>(); 
if (searchConstraint.getAreaMin() != null) 
    predicates.add(cb.gt(root.get(Property_.area), searchConstraint.getAreaMin())) 
if (searchConstraint.getAreaMax() != null) 
    predicates.add(cb.lt(root.get(Property_.area), searchConstraint.getAreaMax())) 
if (predicates.size() > 0) 
    cb.and(predicates.toArray(new Predicate[predicates.size()])) 
相关问题