Specyfikacja interfejsu JPA (Java Persistence API) dla wyrażeń IN
definiuje, że parametr wejściowy o wartości w postaci kolekcji nie jest
ujmowany w nawiasy. Produkt OpenJPA zezwala na obecność nawiasów, podczas gdy
produkt EclipseLink zgłasza wyjątek w przypadku wywołania metody
Query.setParameter z obiektem kolekcji odpowiadającym parametrowi
wejściowemu o wartości w postaci kolekcji IN ujętym w nawiasy.
Ta reguła wykrywa łańcuchy zawierające instrukcje języka JPQL (Java Persistence
Query Language) z wyrażeniami IN o jednym parametrze ujętym w
nawiasy.
Z uwagi na to, że łańcuch zapytania i odpowiadające mu wywołanie
setParameter mogą znajdować się w różnych klasach, reguła nie może
zagwarantować, że parametr będzie kolekcją.
Jeśli parametr jest typu kolekcji, należy usunąć nawiasy z łańcucha zapytania.
Należy zwrócić uwagę, że nawiasy są poprawne dla literałów lub parametrów
wejściowych o pojedynczej wartości, dlatego należy zachować ostrożność podczas
usuwania.
W celu rozwiązania tego problemu należy usunąć nawiasy z wyrażenia
IN z parametrem wejściowym o wartości w postaci kolekcji.
Produkt OpenJPA na przykład zezwala na nawiasy w następujących łańcuchach
zapytań, ale produkt EclipseLink zgłasza wyjątek po wywołaniu metody
setParameter i próbie ustawienia ids na wartość
będącą kolekcją.
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);
|
Aby rozwiązać ten problem, należy usunąć nawiasy, gdy ids
reprezentuje kolekcję.
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);
|
Poniżej został przedstawiony przykład, który został oznaczony flagą, ale nie
powinien zostać zmieniony, ponieważ id jest parametrem o
pojedynczej wartości.
String idMatch = getIdToQuery();
Query query = em.createQuery(SELECT p FROM Person p WHERE p.id IN (:id));
query.setParameter("id", idMatch);
|
Informacje o tym problemie i innych problemach dotyczących migracji środowiska OpenJPA do środowiska EclipseLink zawierają następujące dokumenty: