Search code examples
javajpajakarta-eenamed-query

In JPA, how would I find all of a type that has a property value and a ManyTomany related entity with a property value?


I want to get all the listeners that have an action with the name "Create".

I have the following entities (simplified for this question):

@Entity
public class Listener
{
    ...elided...

    @ManyToMany(targetEntity = Action.class, fetch = FetchType.EAGER)
    @JoinTable(
        name = "ListenerActions",
        joinColumns = @JoinColumn( name = "listenerId", referencedColumnName = "id" ),
        inverseJoinColumns = @JoinColumn( name = "actionId", referencedColumnName = "id" )
    )
    List<Action> actions;
}

@Entity
public class Action
{
    ...elided...

    private String name;
}

How do I filter on the list of actions? I only need one of the actions in a Listener's "actions" to have the name "Create".


Solution

  • A path expression in a JPA 2 query can navigate to a collection-valued field, including across a one-to-many or many-to-many relationship, but that must be the last step in the path; JPA does not permit you to write a path expression that navigates further from there. Therefore, to perform the kind of filtering you want to do, you need to perform a join or create a subquery. The JPA 2.0 specifications provide this example of the former:

    SELECT DISTINCT o
    FROM Order o JOIN o.lineItems l 
    WHERE l.product.productType = 'office_supplies'
    

    , which has the form you want.

    Adapting that to your schema is left as an exercise.