2013-01-15 12 views
7

Chcę znaleźć elementy, które zawierają wszystkie podanych znaczników w ich zestawie znaczników.Znajdowanie pozycji z zestawem zawierającym wszystkie elementy danego zestawu z jpql

Oto uproszczone klas:

@Entity 
class Item { 
    @ManyToMany 
    var tags: java.util.Set[Tag] = new java.util.HashSet[Tag]() 
} 

@Entity 
class Tag { 
    @ManyToMany(mappedBy="tags") 
    var items: java.util.Set[Item] = new java.util.HashSet[Item] 
} 

Gdy próbuję go jak ten

select distinct i 
from Item i join i.tags t 
where t in (:tags) 

uzyskać pozycje, które zawierają żadnego z podanych tagów. Nie jest to zaskakujące, ale chcę, aby Elementy zawierały dane znaczników. Więc staram mu odwrót:

select distinct i 
from Item i join i.tags t 
where (:tags) in t 

dostaję komunikat o błędzie org.hibernate.exception.SQLGrammarException: arguments of row IN must all be row expressions. Działa, jeśli tags zawiera tylko jeden tag, ale kończy się niepowodzeniem.

Jak mogę wyrazić to w JPQL?

+0

Bo myślę, że nie można porównać zestawu z inną tablicą w stanie hibernacji. Myślę, że musisz napisać ponownie kod zapytania SQL. –

+0

Zapytanie kwerendy = session.createQuery ("from Stock where stockId in (: code)"); query.setParameterList ("code", idList); –

+0

Rozumiem, że w swoim pytaniu pokazałeś, jak zdobyć przedmioty, które zawierają któryś z podanych tagów! Tego właśnie szukałem. Mogę potwierdzić, że działa również z elementami @ ElementCollection. –

Odpowiedz

8

Sztuką jest wykorzystanie Count:

select i from Item i join i.tags t 
where t in :tags group by i.id having count(i.id) = :tagCount 
+0

Jest to jedna z tych rzeczy, które zabierają Cię na zawsze, a kiedy to zrobisz, nie możesz uwierzyć, że nie widzisz tego cały czas –

2

prostu miałem ten sam problem jak ty. Użyłem reductio ad absurdum:

select distinct i from Item i where i not in (select i2 from Item i2 join i2.tags t where t not in :tags) 
+0

Podoba mi się ta metoda, ponieważ już miałem zapytanie, które zwróciło to, co zrobiłem Nie chcę, ale musiałem dodać kilka warunków do wewnętrznej selekcji, aby wyniki sub zapytania pozostały małe. Zamiast tego użyłem metody liczenia opisanej tutaj http://stackoverflow.com/a/21645545/429896, która nie wymaga dodawania rzeczy po "grupie przez". – HypeXR

Powiązane problemy