JPA 2.0 CriteriaQuery,类型谓词是

时间:2015-06-09 12:32:02

标签: java java-ee eclipselink jpa-2.0

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

@Entity
Class Ticket {

    @ManyToOne(optional = true)
    private Customer customer;    

}

@Entity
Class Customer {}

@Entity
Class Person extends Customer {}

@Class CustomPerson extends Person {}

如何查询所有类型为Person customer或Person 的任何子类(即CustomPerson)的票证?

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

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

但这会过滤掉CustomPerson

除非有通用方式来处理这个问题(在JPA 2.0中),否则如果我能在运行时确定扩展Person的所有实体,我就可以解决这个问题。在这种情况下,我可以使用

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

2 个答案:

答案 0 :(得分:3)

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

JPA 2.1介绍'治疗'它允许你对实体进行向下转换和操作,就好像它是某个类一样。由于任何子类也是一个实例,因此它会根据您的需要进行过滤。 https://wiki.eclipse.org/EclipseLink/Release/2.5/JPA21#Treat

您可以将它用作连接或where子句,但示例可能是:

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

答案 1 :(得分:0)

如果在较新版本的JPA中没有简单的方法,您可以从底层Session获取映射元数据并以编程方式查找所有映射的子类(您可以懒得并缓存结果)。

参加会议:

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