2013-03-21 24 views
7

Sto provando a scrivere una query JPQL per restituire le entità in cui tutti i figli di quell'entità hanno una proprietà che si trova in un insieme di valori. E 'simile alla seguente domanda, ma dove ci sono più valori possibili:JPA Query - JPQL per selezionare i genitori che hanno TUTTI i bambini con una proprietà in un SET di valori

Hibernate query - How to select those parents that have ALL the children matching a value?

Ecco un esempio pratico tratto dal domanda di cui sopra ...

voglio selezionare quei padri che hanno TUTTI i loro figli che sono biondi o rossi. Se solo uno ha i capelli neri, il padre non è selezionato.

Ho provato vari adattamenti della risposta alla domanda di cui sopra come ...

select p from parent where all(parent.children.haircolor) IN ('blonde','redhead') 

o

select p from parent where parent.children.haircolor ALL IN ('blonde','redhead') 

non riusciva aspettarsi quelli al lavoro, ma vale la pena provare. Finora solo una cosa ha funzionato ...

select p from parent 
where 0 = (select count(c) from p.children c 
       where c.haircolor NOT IN ('blonde','redhead') 
     ) 

mi piacerebbe davvero preferisco non dover eseguire una query conteggio per ogni riga, ma io non sto vedendo un meccanismo migliore. Questo non mi sorprende del tutto dal momento che non riesco a pensare a nessun altro modo di scrivere questo in SQL, ma non sono nemmeno un guru. C'è un modo più efficiente per realizzare questo?

risposta

3

Si tenta di utilizzare le espressioni di percorso JPQL su ciò che sembra una proprietà di raccolta - non è possibile farlo. Invece fare un join come questo:

SELECT p FROM Parent p JOIN p.children c WHERE c.haircolor IN :hairColorCollection 

Sopra, Parent si presume essere un'entità con una proprietà della raccolta prezioso children di cui ogni entità di destinazione ha un singolo valore haircolor proprietà. :hairColorCollection è un parametro che deve essere impostato su un oggetto di raccolta prima dell'esecuzione della query.

+5

L'aggiunta del parametro di raccolta è stata pianificata, ma ciò comporta un tipico join interno. Restituirebbe le entità in cui QUALUNQUE dei bambini corrisponde alla collezione. Il problema qui è che tutti i bambini devono avere una corrispondenza prima che il genitore venga restituito. – nfdavenport

Problemi correlati