将空列表作为参数传递给 JPA 查询会引发错误

2022-08-31 20:59:26

如果我将空列表传递到 JPA 查询中,则会出现错误。

例如:

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();

因为列表是空的,Hibernate在SQL中将其生成为“IN()”,这给我带来了高超音速数据库的错误。

在Hibernate问题跟踪中有一个票证,但那里没有太多的评论/活动。我不知道其他ORM产品或JPA规范中的支持。

我不喜欢每次都必须手动检查空对象和空列表的想法。有没有一些众所周知的方法/扩展?您如何处理这些情况?


答案 1

根据 JPA 1.0 规范中的表达式中的 4.6.8 节:

逗号分隔列表中必须至少有一个元素来定义表达式的值集。IN

换句话说,无论Hibernate解析查询和传递的能力如何,无论特定数据库是否支持这种语法(PosgreSQL不根据Jira问题),如果您希望代码可移植,则应在此处使用动态查询(我通常更喜欢使用标准API进行动态查询)。IN()


答案 2

假设 SQL 查询类似于

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

现在,如果列表的类型为字符串,则可以作为

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

如果 List 包含 Integer 值,则语法如下所示:

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