Opal
Opal

Reputation: 84784

How to filter child collection in JPQL query?

I've the following DB model:

Category -< ProductCategory >- Product -< Variant

(Category has many-to-many relationship with Product and Product has one-to-many relationship with Variant)

Now I need to get all Category records that have product with active variants. I'm getting these objects via the following JPQL query:

@Query("select distinct c from Category c join c.products as p join p.variants as pv where pv.active = true")

It works well - returns categories accurately - however every single Category contains all the products - not only these with active variants.

How can I filter out the products (or variants) that are inactive in a single query?

Here's a postgres script that with database struct and sample data. For given data two categories (CAT 1, CAT 2), two products (PROD 1, PROD 2) and three variants (VAR 1, VAR 2, VAR 3) should be returned.

Upvotes: 10

Views: 12735

Answers (2)

Tong Jin
Tong Jin

Reputation: 21

I have the same problem on it, and I found that the FetchType in the @OneToMany annotation is important. It need to be set as Lazy mode. If it is Eager mode, jpa will create the sql query to fetch the data from the table for your child collection and won't filter it for you.

Upvotes: 2

eztam
eztam

Reputation: 3841

I had exactly the same problem and it took me a while to find out how this works. The child list should be filtered when you add FETCH after your JOIN like this:

SELECT DISTINCT c FROM Category c JOIN FETCH c.products as p join p.variants as pv where pv.active = true

Upvotes: 16

Related Questions