La spécification Java Persistence API (JPA) pour les expressions IN définit qu'un paramètre d'entrée dont la valeur est une collection n'est pas encadré par des parenthèses. OpenJPA permet d'utiliser des parenthèses, tandis que EclipseLink génère une exception lorsque vous appelez la méthode Query.setParameter avec un objet collection correspondant à un paramètre d'entrée dont la valeur est une collection IN entre parenthèses.
Cette règle détecte les chaînes contenant des instructions JPQL (Java Persistence Query Language) avec des expressions IN dont un seul paramètres est encadré par des parenthèses.
Comme la chaîne de requête et l'appel correspondant de setParameter peut se trouver dans différentes classes, la règle ne peut pas garantir que le paramètre est une collection.
Si le paramètre est du type collection, supprimez de la chaîne de recherche les parenthèses.
Notez que les parenthèses sont valides pour les littéraux ou les paramètres d'entrée à valeur unique, donc faites attention à ce que vous supprimez.
Ce problème est résolu en supprimant les parenthèses d'une expression IN avec un paramètre d'entrée avec valeur de collection.
Par exemple, OpenJPA permet d'utiliser des parenthèses dans les chaînes de requête ci-dessous, mais EclipseLink génère une exception lorsque vous appelez setParameter et que vous essayez de définir ids sur une valeur qui est une collection.
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);
|
Pour corriger ce problème, supprimez les parenthèses lorsqu'ids représente une collection.
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);
|
Le code ci-dessous présente un exemple marqué, mais qui ne doit pas être modifié, car id est un paramètre à valeur unique.
String idMatch = getIdToQuery();
Query query = em.createQuery(SELECT p FROM Person p WHERE p.id IN (:id));
query.setParameter("id", idMatch);
|
Pour plus d'informations sur ce problème et sur d'autres problèmes concernant la migration d'OpenJPA vers EclipseLink, voir :