假设以下实体类和层次结构:
@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);
答案 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();