JPQL IN-Klausel: Java-Arrays (oder Listen, Mengen…)?

106

Ich möchte alle Objekte aus unserer Datenbank laden, für die ein Text-Tag auf eine kleine, aber beliebige Anzahl von Werten festgelegt ist. Der logische Weg, dies in SQL zu tun, wäre das Erstellen einer "IN" -Klausel. JPQL erlaubt IN, aber es scheint erforderlich zu sein, dass ich jeden einzelnen Parameter direkt für IN spezifiziere (wie in "in (: in1 ,: in2 ,: in3)").

Gibt es eine Möglichkeit, ein Array oder eine Liste (oder einen anderen Container) anzugeben, die auf die Werte einer IN-Klausel abgewickelt werden sollen?

Bernd Haug
quelle

Antworten:

205

Ich bin mir für JPA 1.0 nicht sicher, aber Sie können ein Collectionin JPA 2.0 übergeben:

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());

Getestet mit EclipseLInk. In Hibernate 3.5.1 müssen Sie den Parameter in Klammern setzen:

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

Dies ist jedoch ein Fehler. Die JPQL-Abfrage im vorherigen Beispiel ist gültiges JPQL. Siehe HHH-5126 .

Pascal Thivent
quelle
5
Gibt es eine maximale Anzahl von Namen, die in "in Klausel" verwendet werden sollen?
Gondim
3
Der oben genannte Fehler in Hibernate scheint in Version 3.6.1
Denis Kniazhev
1
@pringlesinn Die Anzahl der Werte in einer IN-Klausel hängt von Ihrem DBMS ab
Tim Büthe
funktioniert in JPA 1.0 (und es ist keine obligatorische Umgebung mit Klammern, aber für die Lesbarkeit sollten Sie)
Javier Larios
Was ist, wenn Sie => item.name in (wie: Namen)
dzgeek
3

Die Orakelgrenze liegt bei 1000 Parametern. Das Problem wurde im Ruhezustand in Version 4.1.7 behoben, obwohl durch Aufteilen der Liste der übergebenen Parameter in 500er-Sets siehe JIRA HHH-1123

Ashish Thukral
quelle
1
Leider wurde dies nicht gelöst. Das Ticket wurde als behoben markiert, aber das Problem (wie in den Kommentaren gezeigt) wurde vom Hibernate-Team nicht behoben.
Druckles
@Druckles um wo? Ich sehe keine Kommentare älter als 2016. Und das waren nur zwei Kommentare, die praktisch nichts anderes sagen als das übliche Internet 'help plz !!! 11 !!!!'. Sie haben keinen Grund angegeben, dem Fehlerbericht als behoben zu vertrauen.
searchengine27
@ searchengine27 Ich sagte, der Bericht wurde nicht gelöst, obwohl er als gelöst markiert wurde. Die Lösung lautete wie von Steve Ebersole berichtet: "Die Lösung hierfür ist, dass wir Benutzer einfach per Protokollierung warnen, wenn dieser Zustand erkannt wird." Die Kommentare von Noel Trout aus dem Jahr 2012 erläutern, warum dies nicht ausreicht.
Druckles
Mit anderen Worten, diese Antwort ist falsch oder bestenfalls irreführend.
Druckles