Clause JPQL IN: Java-Arrays (ou Lists, Sets…)?

108

Je voudrais charger tous les objets qui ont une balise textuelle définie sur l'un d'un petit nombre arbitraire de valeurs de notre base de données. La manière logique de procéder dans SQL serait de créer une clause "IN". JPQL autorise IN, mais il semble me demander de spécifier chaque paramètre à IN directement (comme dans, "in (: in1,: in2,: in3)").

Existe-t-il un moyen de spécifier un tableau, ou une liste (ou un autre conteneur) qui doit être déroulé aux valeurs d'une clause IN?

Bernd Haug
la source

Réponses:

208

Je ne suis pas sûr pour JPA 1.0 mais vous pouvez passer un Collectiondans 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());

Testé avec EclipseLInk. Avec Hibernate 3.5.1, vous devrez entourer le paramètre de parenthèses:

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

Mais c'est un bogue, la requête JPQL dans l'exemple précédent est JPQL valide. Voir HHH-5126 .

Pascal Thivent
la source
5
y a-t-il un nombre maximum de noms à utiliser dans "dans la clause"?
Gondim
3
Le bogue susmentionné dans Hibernate semble être corrigé dans la version 3.6.1
Denis Kniazhev
1
@pringlesinn le nombre de valeurs dans une clause IN dépend de votre SGBD
Tim Büthe
fonctionne dans JPA 1.0 (et ce n'est pas un encadrement obligatoire entre parenthèses, mais pour la lisibilité, vous devriez)
Javier Larios
et si vous voulez => item.name dans (comme: noms)
dzgeek
3

La limite d'Oracle est de 1000 paramètres. Le problème a été résolu par hibernate dans la version 4.1.7 bien qu'en divisant la liste des paramètres passés en ensembles de 500 voir JIRA HHH-1123

Ashish Thukral
la source
1
Malheureusement, cela n'a pas été résolu. Le ticket a été marqué comme résolu, mais le problème (comme indiqué par les commentaires) n'a pas été résolu par l'équipe Hibernate.
Druckles
@Druckles um où? Je ne vois pas de commentaires antérieurs à 2016. Et ce n'étaient que deux commentaires qui ne disent pratiquement rien d'autre que l'internet habituel 'help plz !!! 11 !!!!'. Vous n'avez donné aucune raison de croire que le rapport de bogue est résolu.
searchengine27
@ searchengine27 J'ai dit que le rapport n'avait pas été résolu, bien qu'il ait été marqué comme résolu. La résolution était, comme l'a rapporté Steve Ebersole: "La résolution à cela est que nous allons simplement avertir les utilisateurs via la journalisation lorsque cette condition est détectée." Les commentaires de Noel Trout en 2012 expliquent pourquoi cela n'est pas suffisant.
Druckles
En d'autres termes, cette réponse est fausse ou, au mieux, trompeuse.
Druckles