콜렉션 값 입력 매개변수를 포함하는 IN 표현식 구문 유효성 검증

IN 표현식에 대한 Java Persistence API(JPA) 스펙은 콜렉션 값 입력 매개변수를 소괄호로 묶지 않도록 정의합니다. 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로의 마이그레이션 관련 문제에 대한 정보는 다음을 참조하십시오.