jpa-2.0 – EclipseLink – 如何在IN运算符中使用空集合?

有没有办法在IN运算符中使用空集合?

List<Integer> idList = new ArrayList<Integer>();
Query query = em.createQuery("SELECT e FROM T e WHERE e.id IN ?1").setParameter(1, idList);
List results = query.getResultList();

生产:

Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
  Position: 48
Error Code: 0
Call: SELECT id, other_id FROM t_table WHERE (id IN ())
Query: ReadAllQuery(referenceClass=T sql="SELECT id, other_id FROM t_table WHERE (id IN ?)")

这个:

List<Integer> idList = new ArrayList<Integer>();

CriteriaBuilder cb = EntityManagerProvider.getEmf().getCriteriaBuilder();
CriteriaQuery<T> c = cb.createQuery(T.class);
Root<T> t_class = c.from(T.class);
Expression<String> exp = t_class.get("id");
Predicate predicate = exp.in(idList);

c.select(t_class).where(predicate);

TypedQuery<T> q = em.createQuery(c);
List results = q.getResultList();   

生产:

Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
  Position: 48
Error Code: 0
Call: SELECT id, other_id FROM t_table WHERE (id IN ())
Query: ReadAllQuery(referenceClass=T sql="SELECT id, other_id FROM t_table WHERE (id IN ())")       

在EN中放置null explicity:

Query query = em.createQuery("SELECT e FROM T e WHERE e.id IN (null)");

生产:

    java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Syntax error parsing the query [SELECT e FROM T e WHERE e.id IN (null)], line 1, column 33: unexpected token [null].
Internal Exception: NoViableAltException(54@[709:9: (itemNode= scalarOrSubSelectExpression ( COMMA itemNode= scalarOrSubSelectExpression )* | subqueryNode= subquery )])

但是,使用本机查询工作正常:

List<Integer> idList = new ArrayList<Integer>();
Query query = em.createNativeQuery("SELECT * FROM t_table WHERE t_table.id IN (null)");
List results = query.getResultList();   

显然,我不想使用本机查询.
当然,我可以在创建查询之前执行if-else检查,并为空集合创建不同的查询,或者在大多数情况下根本不创建查询,因为在简单查询中不会有任何结果.
但是我必须在大型项目中将供应商从OpenJPA(接受空集合)更改为EclipseLink,有时查询在不同的IN中包含很少的集合,因此如果 – 这样就不会那么容易了.

最佳答案 简单的答案是:使用IN查询时,不能使用空数组/列表并将其设置为参数.

您可以使用字符串集中构建查询,如果列表为空/ size()== 0,则不要将IN部分添加到查询字符串中,也不要设置参数.

如果在IN参数中有一个空集合,则生成的查询没有区别,您可以删除此条件.
除了你的目标是真的找不到结果.但从逻辑上讲,您可以在执行查询之前捕获此信息,因为在您的示例中:

“SELECT * FROM t_table WHERE t_table.id IN (null)”

=>可能需要:
a)所有结果均有效=>然后你可以简单地删除where条件
b)没有结果有效=>那么你不需要执行查询,只需在方法中返回一个空的t_table列表.

塞巴斯蒂安

点赞