La specifica JPA (Java Persistence API) per le espressioni IN definisce che un parametro di input con valori di raccolta non è racchiuso tra parentesi. OpenJPA consente l'utilizzo delle parentesi, mentre EclipseLink genera un'eccezione quando si chiama il metodo Query.setParameter con un oggetto di raccolta che corrisponde ad un parametro di input con valori di raccolta IN tra parentesi.
Questa regola rileva le stringhe contenenti istruzioni JPQL (Java Persistence Query Language) con espressioni IN che hanno un unico parametro racchiuso tra parentesi.
Perché la stringa di query e la chiamata corrispondente a setParameter potrebbero essere in classi diverse, la regola non può garantire che il parametro sia una raccolta.
Se il parametro è del tipo raccolta, rimuovere le parentesi dalla stringa di query.
Le parentesi sono valide per i valori letterali o per i parametri di input con valore singolo, quindi prestare attenzione a ciò che si rimuove.
Questo problema viene risolto rimuovendo le parentesi da un'espressione IN con un parametro di input con valore raccolta.
Ad esempio, OpenJPA consente l'utilizzo delle parentesi nelle seguenti stringhe di query, mentre EclipseLink genera un'eccezione quando si chiama setParameter e si tenta di impostare ids con un valore che è una raccolta.
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);
|
Per risolvere questo problema, rimuovere le parentesi quando ids rappresenta una raccolta.
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);
|
Il seguente frammento di codice riporta un esempio contrassegnato ma che non dovrebbe essere modificato perché id è un parametro a valore singolo.
String idMatch = getIdToQuery();
Query query = em.createQuery(SELECT p FROM Person p WHERE p.id IN (:id));
query.setParameter("id", idMatch);
|
Per informazioni su questo problema ed altri problemi relativi alla migrazione da OpenJPA a EclipseLink, consultare: