Clausola JPQL IN: Java-Arrays (o Lists, Sets…)?


108

Vorrei caricare tutti gli oggetti che hanno un tag testuale impostato su uno qualsiasi di un numero piccolo ma arbitrario di valori dal nostro database. Il modo logico per farlo in SQL sarebbe creare una clausola "IN". JPQL consente IN, ma sembra richiedermi di specificare ogni singolo parametro direttamente su IN (come in, "in (: in1,: in2,: in3)").

Esiste un modo per specificare un array o un elenco (o qualche altro contenitore) che dovrebbe essere srotolato ai valori di una clausola IN?

Risposte:


208

Non sono sicuro per JPA 1.0 ma puoi passare Collectiona JPA 2.0:

String qlString = "select item from Item item where item.name IN :names"; 
Query q = em.createQuery(qlString, Item.class);

List<String> names = Arrays.asList("foo", "bar");

q.setParameter("names", names);
List<Item> actual = q.getResultList();

assertNotNull(actual);
assertEquals(2, actual.size());

Testato con EclipseLInk. Con Hibernate 3.5.1, dovrai racchiudere il parametro tra parentesi:

String qlString = "select item from Item item where item.name IN (:names)";

Ma questo è un bug, la query JPQL nell'esempio precedente è JPQL valida. Vedere HHH-5126 .


5
c'è un numero massimo di nomi da utilizzare nella "clausola in"?
Gondim

3
Il suddetto bug in Hibernate sembra essere stato corretto nella versione 3.6.1
Denis Kniazhev

1
@pringlesinn il numero di valori in una clausola IN dipende dal tuo DBMS
Tim Büthe

funziona in JPA 1.0 (e non è obbligatorio circondare tra parentesi, ma per leggibilità dovresti)
Javier Larios

cosa succede se vuoi => item.name in (come: nomi)
dzgeek

3

Il limite Oracle è di 1000 parametri. Il problema è stato risolto da ibernazione nella versione 4.1.7 sebbene suddividendo l'elenco dei parametri passati in set di 500 vedere JIRA HHH-1123


1
Purtroppo questo non è stato risolto. Il ticket è stato contrassegnato come risolto, ma il problema (come mostrato dai commenti) non è stato risolto dal team di Hibernate.
Druckles

@Druckles um dove? Non vedo commenti precedenti al 2016. E quelli erano solo due commenti che non dicono praticamente nient'altro che il solito Internet "help plz !!! 11 !!!!". Non hai dato motivo di fidarti della segnalazione di bug come risolta.
searchengine27

@ searchengine27 Ho detto che il rapporto non è stato risolto, nonostante fosse contrassegnato come risolto. La risoluzione è stata, come riportato da Steve Ebersole: "La risoluzione è che avviseremo semplicemente gli utenti tramite la registrazione quando viene rilevata questa condizione". I commenti di Noel Trout nel 2012 ampliano il motivo per cui questo non è sufficiente.
Druckles

In altre parole, questa risposta è sbagliata o, nella migliore delle ipotesi, fuorviante.
Druckles
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.