Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA Query - JPQL to select parents that have ALL children with a property in a SET of values

I'm trying write a JPQL query to return entities where all of that entity's children have a property that is in a set of values. It is similar to the following question, but where there are multiple possible values:

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

Here is a practical example adapted from the above question...

I want to select those fathers who have ALL their children who are either blond or redhead. If just one is black haired the father is not selected.

I've tried various adaptations of the answer to the above question like...

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

or

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

Didn't quite expect those to work, but worth a try. So far only one thing HAS worked...

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

I'd really prefer not to have to run such a count query for every row, but I'm not seeing a better mechanism. This doesn't totally surprise me since I can't quite think of any other way to write this in plain SQL, but I'm not a guru there either. Is there a more efficient way to accomplish this?

like image 905
nfdavenport Avatar asked Mar 21 '13 04:03

nfdavenport


People also ask

What is the use of @query in JPA?

Understanding the @Query Annotation The @Query annotation can only be used to annotate repository interface methods. The call of the annotated methods will trigger the execution of the statement found in it, and their usage is pretty straightforward. The @Query annotation supports both native SQL and JPQL.

Which is JPQL aggregate function?

JPQL supports the five aggregate functions of SQL: COUNT - returns a long value representing the number of elements. SUM - returns the sum of numeric values. AVG - returns the average of numeric values as a double value.

Which JPQL keyword is used to determine whether a value is an element of a collection in JPA?

This example shows how to use JPQL keyword MEMBER OF to determine whether a value is an element of a collection.


1 Answers

You try to use JPQL path expressions over what looks like a collection property - you can't do that. Instead do a join like this:

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

Above, Parent is assumed to be an entity with a collection valued property children of which every target entity has a single valued haircolor property. :hairColorCollection is a parameter which should be set to a collection object before executing the query.

like image 135
rdcrng Avatar answered Sep 28 '22 09:09

rdcrng