HQL checks the size of the list passed in @param
Is there a way to check util. What size is List
? For example, is it empty?
I tried the query below and it generated
with message ???QuerySyntaxException
unmapped
.. where (:filters IS EMPTY or (d.id in (:filters))")
List<EntityXX> getXXX(List<Integer> filters);
Solution
As dbl replied in his comment, it is not possible to check the size of List<> passed as an @Param.
You are using HQL,
so since JPQL queries are always valid HQL queries, I would like to share my solution.
@Query("SELECT p FROM Product p "
+ "LEFT JOIN p.categories category "
+ "WHERE p.name LIKE CONCAT('%', :searchRequest, '%') "
+ "AND p.description LIKE CONCAT('%', :description, '%') "
+ "AND p.price BETWEEN :priceLow AND :priceHigh "
+ "AND p.archived = :archived "
+ "AND category.name IN :selectedCategories "
+ "GROUP BY p "
+ "HAVING SIZE(p.categories) >= :amountOfSelectedCategories"
)
Page<Product> findAllBySearchModel(
Pageable pageable,
@Param("searchRequest") String searchRequest,
@Param("description") String description,
@Param("priceLow") BigDecimal priceLow,
@Param("priceHigh") BigDecimal priceHigh,
@Param("archived") boolean archived,
@Param("selectedCategories") List<String> selectedCategories,
@Param("amountOfSelectedCategories") int amountOfSelectedCategories
);
Since WHERE… The IN clause always uses an OR condition, and I wanted to narrow my search and I had to find another way to further limit my results.
Therefore, I need the size of the incoming list.
In JPQL, you can easily use SIZE(), except for @Param.
This resulted in a complete workaround to add the size of my list as an extra @Param. I also check for an empty list in my service layer.
if (!searchModel.getSelectedCategories().isEmpty()) {
return productService.findAllBySearchModel(
pageable,
searchModel.getSearchRequest(),
searchModel.getDescription(),
searchModel.getPriceLow(),
searchModel.getPriceHigh(),
searchModel.isArchivedView(),
searchModel.getSelectedCategories(),
searchModel.getSelectedCategories().size()
);
}
*Note: My code is a bit simplified and not production environment compliant. I just wanted to give a small example for those struggling with the same problem.