Passing empty list as parameter to JPA query throws error

If I pass an empty list into a JPA query, I get an error. For example:

List<Municipality> municipalities = myDao.findAll();  // returns empty list
em.createQuery("SELECT p FROM Profile p JOIN p.municipality m WHERE m IN (:municipalities)")
    .setParameter("municipalities", municipalities)
    .getResultList();

Because the list is empty, Hibernate generates this in SQL as "IN ()", which gives me error with Hypersonic database.

There is a ticket for this in Hibernate issue tracking but there are not many comments/activity there. I don't know about support in other ORM products or in JPA spec either.

I don't like the idea of having to manually check for null objects and empty lists every time. Is there some commonly known approach/extension to this? How do you handle these situations?


Solution 1:

According to the section 4.6.8 In Expressions from the JPA 1.0 specification:

There must be at least one element in the comma separated list that defines the set of values for the IN expression.

In other words, regardless of Hibernate's ability to parse the query and to pass an IN(), regardless of the support of this syntax by particular databases (PosgreSQL doesn't according to the Jira issue), you should use a dynamic query here if you want your code to be portable (and I usually prefer to use the Criteria API for dynamic queries).

Solution 2:

Assuming the SQL query to be like

(COALESCE(:placeHolderName,NULL) IS NULL OR Column_Name in (:placeHolderName))

Now, If the List is of type String then you can pass as

query.setParameterList("placeHolderName", 
!CollectionUtils.isEmpty(list)? list : new ArrayList<String>(Arrays.asList("")).

And If the List is containing the Integer values then the syntax is like below:

If(!CollectionUtils.isEmpty(list)){
query.setParameterList("placeHolderName",list)
}else{
query.setParameter("placeHolderName",null, Hibernate.INTEGER)
}

Solution 3:

I struggled with this issue, too. I found out that the Hibernate community has RESOLVED the issue in Hibernate version 5.4.10, here is the ticket: https://hibernate.atlassian.net/browse/HHH-8091

You can check your Hibernate version System.out.println(org.hibernate.Version.getVersionString());

And you can UPDATE the version of Hibernate to the latest, here is a useful link: https://hibernate.org/orm/releases/