How do I query for only superclass entities in a jpql query?

Kyle Renfro picture Kyle Renfro · Sep 22, 2010 · Viewed 10.9k times · Source

I have the following entities:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="orderType", discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue(value="BASE")
@Table(name = "orders")
public class OrderEntity implements Serializable {
...

and

@Entity
@DiscriminatorValue(value="RECURRING")
public class RecurringOrderEntity extends OrderEntity{
...

I can find all the subclasses (RecurringOrderEntity) with the following jpql:

Query q = em.createQuery(
                "SELECT o from RecurringOrderEntity o where "
                + "o.cancellationDate is null "
                + "and o.maxOccurrences = o.occurrence");

What is the JPQL syntax for finding only entities that are not instances of RecurringOrderEntity?

I am using Eclipselink 2.0.0 as the JPA provider.

thanks!

Answer

Pascal Thivent picture Pascal Thivent · Sep 22, 2010

What is the JPQL syntax for finding only entities that are not instances of RecurringOrderEntity?

Use an entity type expression with the TYPE operator. Something like this (not sure about the exact query you want but you get the idea):

SELECT o 
FROM OrderEntity o 
WHERE TYPE(o) <> RecurringOrderEntity
  AND o.cancellationDate is null
  AND o.maxOccurrences = o.occurrence

Below, the relevant section of the JPA 2.0 specification:

4.6.17.4 Entity Type Expressions

An entity type expression can be used to restrict query polymorphism. The TYPE operator returns the exact type of the argument.

The syntax of an entity type expression is as follows:

entity_type_expression ::=
       type_discriminator |
       entity_type_literal |
       input_parameter
type_discriminator ::=
       TYPE(identification_variable |
            single_valued_object_path_expression |
            input_parameter )

An entity_type_literal is designated by the entity name.

The Java class of the entity is used as an input parameter to specify the entity type.

Examples:

SELECT e
FROM Employee e
WHERE TYPE(e) IN (Exempt, Contractor)

SELECT e
FROM Employee e
WHERE TYPE(e) IN (:empType1, :empType2)

SELECT e
FROM Employee e
WHERE TYPE(e) IN :empTypes

SELECT TYPE(e)
FROM Employee e
WHERE TYPE(e) <> Exempt