コレクション値の入力パラメーターを使用した IN 式の構文を検証しなければならない

Java Persistence API (JPA) 仕様は、IN 式について、コレクション値の入力パラメーターは括弧で囲まれないと規定しています。OpenJPA では括弧の存在が許可されていますが、EclipseLink では、括弧で囲まれた IN コレクション値の入力パラメーターに対応するコレクション・オブジェクトを指定して Query.setParameter メソッドを呼び出すと、例外がスローされます。

この規則は、単一パラメーターが括弧で囲まれている IN 式のある Java Persistence Query Language (JPQL) ステートメントが含まれているストリングを検出します。 照会ストリングと、対応する setParameter 呼び出しが別々のクラスに含まれている可能性があるため、この規則はパラメーターがコレクションであることを保証できません。 パラメーターがコレクション型の場合、括弧を照会ストリングから削除してください。 リテラルまたは単一値の入力パラメーターでは括弧は有効であるため、何を削除するのかについては慎重に判断してください。

この問題を解決するには、コレクション値の入力パラメーターが含まれている IN 式から括弧を削除します。

例えば、OpenJPA では以下の照会ストリング中の括弧は許可されますが、EclipseLink では、 setParameter を呼び出し、コレクションである値に ids を設定しようとすると、例外がスローされます。

  List<String> idList = getIdsToQuery();
  Query query = em.createQuery("SELECT p FROM Person p WHERE p.id IN (:ids)");
  query.setParameter("ids", idList);
  
  final String ENTITY_NAME = "Person";
  final String PRIMARY_KEY = "id";
  List<String> idList2 = getIdsToQuery();
  Query query = em.createQuery("SELECT p FROM " + ENTITY_NAME + " p " +" WHERE p." + PRIMARY_KEY + " IN (:ids)");
  query.setParameter("ids", idList2);

この問題を修正するには、ids がコレクションを表す場合に括弧を削除します。

  List<String> idList = getIdsToQuery();
  Query query = em.createQuery("SELECT p FROM Person p WHERE p.id IN :ids");
  query.setParameter("ids", idList);
  
  final String ENTITY_NAME = "Person";
  final String PRIMARY_KEY = "id";
  List<String> idList2 = getIdsToQuery();
  Query query = em.createQuery("SELECT p FROM " + ENTITY_NAME + " p " +" WHERE p." + PRIMARY_KEY + " IN :ids");
  query.setParameter("ids", idList2);

以下の例では、フラグが立てられますが、id は単一値パラメーターであるため変更する必要はありません。


  String idMatch = getIdToQuery();
  Query query = em.createQuery(SELECT p FROM Person p WHERE p.id IN (:id));
  query.setParameter("id", idMatch);
  

この問題や他の OpenJPA から EclipseLink へのマイグレーションの問題については、以下を参照してください。