I have one query that should filter based on various parameters; one of those parameters is a list. If there are entries in the list, there should be a filtering based on the entries; but if the list is empty/null, there shouldn't be any filtering on that field.
What I've thought is something like this:
@Query("select a from Alert a where a.date >= :startDate " +
"and (((:countryIds) is null) or a.countryId in (:countryIds)) " +
"and (((:typeIds) is null) or a.siteTypeId in (:typeIds)) ")
List<Alert> findBy(@Param("startDate") Date startDate,
@Param("countryIds") Set<Long> countryIds,
@Param("typeIds") Set<Long> typeIds);
Sending null List it throws NPE; sending an empty list it generates the following SQL, which is invalid
where alert0_.date >= '2018-01-01' and
((1, 123) is null or alert0_.countryId in (1, 123))
I've also tried in JPQL to have and (((:countryIds) is empty) or a.countryId in (:countryIds))
but it also doesn't work when trying to compile the JPQL (at application startup): Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: ??? is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:171)
Or using SpEL:
"and (:#{countryIds.size() > 0} or (a.countryId in (:countryIds))) "
but again, it doesn't compile the JPQL.
The only solution I've thought is to dynamically generate the JPQL which is ugly or to populate all existing values for countryIds
and siteTypeIds
which is inefficient.
JPA implementation is Hibernate and database is MySQL.