JPA 2.0 CriteriaQuery,类型的谓词是类或任何子类

Cas*_*der 5 java eclipselink java-ee jpa-2.0

假设以下实体类和层次结构:

@Entity
Class Ticket {

    @ManyToOne(optional = true)
    private Customer customer;    

}

@Entity
Class Customer {}

@Entity
Class Person extends Customer {}

@Class CustomPerson extends Person {}
Run Code Online (Sandbox Code Playgroud)

如何查询具有customerPerson类型 Person的任何子类(即CustomPerson)的所有票证?

我可以轻松地在类型上创建谓词:

Predicate p = criteriaBuilder.equal(Ticket_...type(), criteriaBuilder.literal(Person.class));
Run Code Online (Sandbox Code Playgroud)

但这会过滤掉CustomPerson.

除非有一种通用的方法来处理这个(在JPA 2.0中),如果我能在运行时确定扩展Person的所有实体,我可以克服这个问题; 在这种情况下,我可以使用

Predicate p = criteriaBuilder.in(Ticket_...type(), listOfPersonSubclasses);
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 3

JPA 2.0 不提供通用方法,因此您必须列出所有子类,或者更改查询以使其基于您的 Person 类。例如"Select t from Person p, ticket t where t.customer=p"

JPA 2.1 引入了“treat”,它允许您对实体进行向下转换和操作,就好像它是某个类一样。由于任何子类也是一个实例,因此它完全按照您的要求进行过滤。 https://wiki.eclipse.org/EclipseLink/Release/2.5/JPA21#Treat

您可以将其用作联接或在 where 子句中使用,但示例可能是:

"Select t from Ticket t join treat(t.customer as Person) p"
Run Code Online (Sandbox Code Playgroud)