有没有办法在 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 ())")
在 IN 中明确放置 null:
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 中包含很少的集合,所以 if-elsing 这不会那么容易。