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 へのマイグレーションの問題については、以下を参照してください。