Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
like image 462
Tasos P. Avatar asked Oct 19 '22 09:10

Tasos P.


1 Answers

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"
like image 166
Chris Avatar answered Oct 29 '22 14:10

Chris