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のコレクションがほとんど含まれていない場合があるため、これを行うのはそれほど簡単ではありません。