Klauzula JPQL IN: tablice Java (lub listy, zestawy…)?


108

Chciałbym załadować wszystkie obiekty, które mają przypisany tag tekstowy do dowolnej małej, ale dowolnej liczby wartości z naszej bazy danych. Logicznym sposobem rozwiązania tego problemu w SQL byłoby zbudowanie klauzuli „IN”. JPQL dopuszcza IN, ale wydaje się, że wymaga ode mnie bezpośredniego określenia każdego parametru na IN (jak w, "in (: in1,: in2,: in3)").

Czy istnieje sposób na określenie tablicy lub listy (lub innego kontenera), które powinny zostać rozwinięte do wartości klauzuli IN?

Odpowiedzi:


208

Nie jestem pewien dla JPA 1.0, ale możesz przejść Collectionw 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());

Przetestowano za pomocą EclipseLInk. W Hibernate 3.5.1 musisz otoczyć parametr nawiasami:

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

Ale to jest błąd, zapytanie JPQL w poprzednim przykładzie jest poprawnym JPQL. Zobacz HHH-5126 .


5
czy istnieje maksymalna liczba nazw do użycia w „w klauzuli”?
Gondim

3
Wspomniany błąd w Hibernate wydaje się być naprawiony w wersji 3.6.1
Denis Kniazhev

1
@pringlesinn liczba wartości w klauzuli IN zależy od twojego DBMS
Tim Büthe

pracuje w JPA 1.0 (i jego brak obowiązkowego przestrzennego z nawiasu, ale dla czytelności zalecana)
Javier Larios

co jeśli chcesz => item.name w (like: names)
dzgeek

3

Limit wyroczni to 1000 parametrów. Problem został rozwiązany przez hibernację w wersji 4.1.7, chociaż przez podzielenie listy przekazanych parametrów na zestawy po 500, patrz JIRA HHH-1123


1
Niestety nie udało się tego rozwiązać. Zgłoszenie zostało oznaczone jako rozwiązane, ale problem (jak pokazują komentarze) nie został naprawiony przez zespół Hibernate.
Druckles

@Druckles um gdzie? Nie widzę żadnych komentarzy starszych niż 2016. A to tylko dwa komentarze, które nie mówią praktycznie nic poza zwykłym internetowym „help plz !!! 11 !!!!”. Nie podałeś żadnego powodu, aby ufać zgłoszeniu błędu jako rozwiązanemu.
Searchengine 27

@earchchengine27 Powiedziałem, że raport nie został rozwiązany, mimo że został oznaczony jako rozwiązany. Rozwiązanie było, jak donosił Steve Ebersole: „Rozwiązanie jest takie, że będziemy po prostu ostrzegać użytkowników poprzez logowanie, gdy ten stan zostanie wykryty”. Komentarze Noela Trouta z 2012 roku wyjaśniają, dlaczego to nie wystarczy.
Druckles

Innymi słowy, ta odpowiedź jest błędna lub w najlepszym przypadku myląca.
Druckles
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.