在JPA中处理空或null集合参数

时间:2017-04-22 12:31:11

标签: hibernate jpa spring-data spring-data-jpa jpql

org.springframework.data.jpa.repository.@Query内注释我检查集合中是否有字段,如果它是空的则可能忽略集合:

@Query(""select e from #{#entityName} where e.type in :lst or 0 = :lstSize")
List<Entity> findByLst(@Param("lst") List<XEnum> lst, @Param("lstSize") int lstSize);

我将代码称为:

List<XEnum> lst = ...;
int lstSize = (lst == null) ? 0 : lst.size();
findByLst(lst, lstSize);

对于lst = null Hibernate记录的情况下的Oracle DB:

DEBUG [nio-8443-exec-4] org.hibernate.SQL
entity0_.type in (?) or 0=?
TRACE [nio-8443-exec-4] org.hibernate.type.EnumType
Binding null to parameter: [1]
TRACE [nio-8443-exec-4] org.hibernate.type.descriptor.sql.BasicBinder
binding parameter [2] as [INTEGER] - [0]

对于lst = new LinkedList<>() Hibernate记录的情况:

DEBUG [nio-8443-exec-5] org.hibernate.SQL
entity0_.type in ( ) or 0=?
TRACE [nio-8443-exec-5] org.hibernate.type.descriptor.sql.BasicBinder
binding parameter [1] as [INTEGER] - [0]
ERROR [nio-8443-exec-5] org.hibernate.engine.jdbc.spi.SqlExceptionHelper
ORA-00936: missing expression

在SQL * PLUS中语法无效:

select 1 from dual where 1 in ();

我可以省略lstSize并仍然检查是否未提供集合 - 返回所有元素吗?

如何处理空列表和Oracle ()语法错误?

实际上我有大型JPQL表达式,可以通过单次调用处理几个空参数。我的目标是保持简单的方法,而不是使用if/else或Critetia构建器编写几个专门的方法......

例如,忽略空参数可以使用以下命令存档:

 ... and (e.field = :fieldVal or :fieldVal is null)

更新相关资源:

2 个答案:

答案 0 :(得分:0)

Criteria API是为了营救。

您正在动态地构建SQL查询(当您通过构建工具插件从实体生成特殊类时,可以使用类型安全的)。

Spring数据以MealplanCalls.getRestaurants(userId: userId) { (restaurantList, error) in if let error = error { self.showError(show: "Error", display: error) } else { var currentPlansArray = [Mealplan]() var restaurantIndex = 0 let group = DispatchGroup() while (restaurantIndex < restaurantList.count) { group.enter() MealplanCalls.getPlans(restaurantId: restaurantList[restaurantIndex]) { (mealplans, error) in guard let mealplans = mealplans, mealplans.count > 0 else { return } self.planArray.append(contentsOf: mealplans) print("empty : \(self.planArray.count), \(self.planArray)") if let error = error { self.showError(show: "Error", display: error) } group.leave() currentPlansArray.removeAll() restaurantIndex += 1 } } group.notify(queue: DispatchQueue.main, execute: { self.planTable.reloadData() }) } } + painter.fillRect(event->rect(), QColor(0, 0, 0)); painter.drawImage(QRectF(event->rect().x(), event->rect().y() + 30, 512, 512), getGameBoardImage()); //...rendering other model components painter.setBrush(QBrush(QColor(255, 255, 255))); //painter.setFont(getGameFont()); painter.setFont(QFont("Times New Roman", 16, QFont::Bold)); painter.drawText(0, 0, "HI-SCORE"); 的形式提供了便利,因此查询可能类似于:

org.springframework.data.jpa.domain.Specification

Hibernate Criteria API在org.springframework.data.jpa.repository.JpaSpecificationExecutorSpecification<Book> spec = (Root<Book> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> { ... if (CollectinUtils.isNotEmpty(ids)) { root.get("id").in(ids); } } List<Book> booksByIds = repository.findAll(spec); 中支持null,而忽略了该表达式,如果将AND运算符构建器放在实用程序函数中,则可以方便地省略空检查。 >

答案 1 :(得分:0)

您可以使用JPA NotEmpty or IsNotEmpty

示例代码

实体

public class products{
  ....fields

  @OneToMany(mappedBy = "productId")
  @JsonIgnore
  private List<Rating> ratingList;

  .....geter/setter
}


public class Rating{
  ....fields
 
 @JoinColumn(name = "product_id", referencedColumnName = "id")
 @ManyToOne
 @JsonIgnore
 private Products productId;

  .....geter/setter

}

存储库

public interface ProductRepository extends JpaRepository<Products, Integer>{
   public Page<Products> findByRatingListNotEmpty(Pageable pg);
}