The Java Persistence API (JPA) specification for IN expressions defines that a collection-valued input parameter
is not surrounded by parentheses. OpenJPA allows the parentheses to be present, whereas EclipseLink
throws an exception when you call the Query.setParameter method with a collection object
corresponding to an IN collection-valued input parameter in parentheses.
This rule detects strings containing Java Persistence Query Language (JPQL) statements with IN expressions
that have a single parameter enclosed by parentheses.
Because the query string and the corresponding
call to setParameter might be in different classes, the rule cannot guarantee that the parameter
is a collection.
If the parameter is a collection type, remove the parentheses from the query string.
Note that parentheses are valid for literals or single-valued input parameters, so be careful about what you remove.
This problem is resolved by removing the parentheses from an IN expression with
a collection-valued input parameter.
For example, OpenJPA allows the parentheses in the following query strings, but EclipseLink
throws an exception when you call setParameter and try to set
ids to a value that is a 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);
|
To fix this problem, remove the parentheses when ids represents a 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);
|
The following shows an example that is flagged but should not be changed
because id is a single-value parameter.
String idMatch = getIdToQuery();
Query query = em.createQuery(SELECT p FROM Person p WHERE p.id IN (:id));
query.setParameter("id", idMatch);
|
For information about this issue and other OpenJPA to EclipseLink migration issues, see: