JPA 2.0 CriteriaQuery 的谓词类型是 class 或任何子 class
JPA 2.0 CriteriaQuery with predicate on type being a class or any subclass of
假设以下实体 类 和层次结构:
@Entity
Class Ticket {
@ManyToOne(optional = true)
private Customer customer;
}
@Entity
Class Customer {}
@Entity
Class Person extends Customer {}
@Class CustomPerson extends Person {}
如何查询具有 customer
类型 Person 或 Person 的任何子类(即 CustomPerson)的所有工单?
我可以轻松地在类型上创建谓词:
Predicate p = criteriaBuilder.equal(Ticket_...type(), criteriaBuilder.literal(Person.class));
但这会过滤掉 CustomPerson
。
除非有 generic 方法来处理这个问题(在 JPA 2.0 中),如果我能在运行时确定所有扩展 Person 的实体,我就可以解决这个问题;在这种情况下我可以使用
Predicate p = criteriaBuilder.in(Ticket_...type(), listOfPersonSubclasses);
如果在较新版本的 JPA 中没有简单的方法,您可以从底层 Session 获取映射元数据并以编程方式查找所有映射的子类(您可以懒惰地执行并缓存结果)。
获取会话:
org.eclipse.persistence.sessions.Session session =
((org.eclipse.persistence.internal.jpa.EntityManagerImpl)
em.getDelegate()).getSession();
JPA 2.0 不提供通用方法,因此您必须列出所有子class,或者更改查询以使其基于您的 Person class。例如"Select t from Person p, ticket t where t.customer=p"
JPA 2.1 引入了 'treat',它允许您向下转换和操作实体,就好像它是某个 class。由于任何 subclass 也是一个实例,因此它会完全按照您的要求进行过滤。 https://wiki.eclipse.org/EclipseLink/Release/2.5/JPA21#Treat
您可以将其用作连接或在 where 子句中使用,但示例可能是:
"Select t from Ticket t join treat(t.customer as Person) p"
假设以下实体 类 和层次结构:
@Entity
Class Ticket {
@ManyToOne(optional = true)
private Customer customer;
}
@Entity
Class Customer {}
@Entity
Class Person extends Customer {}
@Class CustomPerson extends Person {}
如何查询具有 customer
类型 Person 或 Person 的任何子类(即 CustomPerson)的所有工单?
我可以轻松地在类型上创建谓词:
Predicate p = criteriaBuilder.equal(Ticket_...type(), criteriaBuilder.literal(Person.class));
但这会过滤掉 CustomPerson
。
除非有 generic 方法来处理这个问题(在 JPA 2.0 中),如果我能在运行时确定所有扩展 Person 的实体,我就可以解决这个问题;在这种情况下我可以使用
Predicate p = criteriaBuilder.in(Ticket_...type(), listOfPersonSubclasses);
如果在较新版本的 JPA 中没有简单的方法,您可以从底层 Session 获取映射元数据并以编程方式查找所有映射的子类(您可以懒惰地执行并缓存结果)。
获取会话:
org.eclipse.persistence.sessions.Session session =
((org.eclipse.persistence.internal.jpa.EntityManagerImpl)
em.getDelegate()).getSession();
JPA 2.0 不提供通用方法,因此您必须列出所有子class,或者更改查询以使其基于您的 Person class。例如"Select t from Person p, ticket t where t.customer=p"
JPA 2.1 引入了 'treat',它允许您向下转换和操作实体,就好像它是某个 class。由于任何 subclass 也是一个实例,因此它会完全按照您的要求进行过滤。 https://wiki.eclipse.org/EclipseLink/Release/2.5/JPA21#Treat
您可以将其用作连接或在 where 子句中使用,但示例可能是:
"Select t from Ticket t join treat(t.customer as Person) p"