Tasos P.
Tasos P.

Reputation: 4124

JPA 2.0 CriteriaQuery with predicate on type being a class or any subclass of

Assuming the following entity classes and hierarchy:

@Entity
Class Ticket {

    @ManyToOne(optional = true)
    private Customer customer;    

}

@Entity
Class Customer {}

@Entity
Class Person extends Customer {}

@Class CustomPerson extends Person {}

How can I query for all tickets which have customer of type Person or any subclass of Person (i.e. CustomPerson)?

I can easily create a predicate on type:

Predicate p = criteriaBuilder.equal(Ticket_...type(), criteriaBuilder.literal(Person.class));

but this will filter out CustomPerson.

Unless there is a generic way to handle this (in JPA 2.0), I could overcome the issue if I could determine at runtime all entities extending Person; in this scenario I could use

Predicate p = criteriaBuilder.in(Ticket_...type(), listOfPersonSubclasses);

Upvotes: 5

Views: 884

Answers (2)

Dragan Bozanovic
Dragan Bozanovic

Reputation: 23562

If there is no easy way in newer versions of JPA, you could get the mapping metadata from the underlying Session and find all the mapped subclasses programmatically (you may do it lazily and cache the results).

To get the session:

org.eclipse.persistence.sessions.Session session = 
     ((org.eclipse.persistence.internal.jpa.EntityManagerImpl) 
                 em.getDelegate()).getSession();

Upvotes: 0

Chris
Chris

Reputation: 21165

JPA 2.0 doesn't offer a generic way, so you would have to list all the subclasses, or change the query so that it is based off your Person class instead. For example "Select t from Person p, ticket t where t.customer=p"

JPA 2.1 introduced 'treat' which allows you to downcast and operate on the entity as if it were a certain class. Since any subclass is also an instance, it filters exactly as you seem to require. https://wiki.eclipse.org/EclipseLink/Release/2.5/JPA21#Treat

You can use it as a join or in the where clause, but an example might be:

"Select t from Ticket t join treat(t.customer as Person) p"

Upvotes: 3

Related Questions