Проверить синтаксис выражения IN с входным параметром, имеющим коллекцию в качестве значения

Согласно спецификации Java Persistence API (JPA), входной параметр со значением-коллекцией в выражении IN не должен заключаться в круглые скобки. OpenJPA допускает наличие круглых скобок, а EclipseLink генерирует исключительную ситуацию в случае вызова метода Query.setParameter, у которого объект коллекции, соответствующий входному параметру IN со значением-коллекцией, заключен в круглые скобки.

Это правило отмечает строки, содержащие операторы Java Persistence Query Language (JPQL) с выражениями IN, единственный входной параметр которых заключен в круглые скобки. Поскольку строка запроса и соответствующий вызов 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, обратитесь к следующим источникам: