Hibernate和PostgreSQL - 检查setParameterList中传递的集合是否为空

时间:2012-11-26 21:52:32

标签: java sql database hibernate postgresql

我正在构建一个查询,我想将一个集合作为参数传递:

List<String> items = new LinkedList();
//adding optional items
Query query = s.getNamedQuery("myQueryName").setParameterList("item", items);

我的查询如下:

SELECT i from Item i
//... not important things
WHERE ( i.name in (:item) )

但我想让它成为可选项,因此项目列表可能为空。但是当它空了,我得到一个例外:

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected end of subtree

所以我尝试使用一些函数,如:

SELECT i from Item i
//... not important things
WHERE ( (:item) is null or i.name in (:item) )

SELECT i from Item i
//... not important things
WHERE ( (:item) is empty or i.name in (:item) )

SELECT i from Item i
//... not important things
WHERE ( size(:item)=0 or i.name in (:item) )

但似乎没有任何效果。如果列表不为空,我该如何解决此问题并检查项目名称是否在列表中?

2 个答案:

答案 0 :(得分:3)

您可以在列表中添加一个您知道永远不会返回true的值。例如,假设您有一个整数列表,并且您想查看列表中是否包含ID。您可以在列表中添加“-1”,它应该按照您想要的方式工作。对于您的字符串示例,只需添加一个永不发生的随机字符串。

类似的东西:

List<String> items = new LinkedList();
items.add("**BLAHBLAH_YO_MAMMA_SO_SLEAZY_SHE_ALWAYS_RETURN_TRUE**");
//add optional items
Query query = s.getNamedQuery("myQueryName").setParameterList("item", items);

答案 1 :(得分:2)

那就是,恕我直言,SQL中的设计问题,当然也存在于HQL中,因为它直接转换为SQL。

在HQL中没有简单的解决方案可以解决这个问题。最简单,最有效的方法是在生成和执行查询之前检查列表。

在许多情况下,您只需要这样做:

if (items.isEmpty()) {
    return Collections.emptyList();
}

在您的情况下,我会使用条件查询(或用于动态构建查询的其他API),并动态构建查询:

Criteria c = session.createCriteria(Item.class, i);
...
if (!items.isEmpty()) {
    c.add(Restrictions.in("i.name", items));
}
return c.list();