Java /JPA |具有指定继承类型的查询
Posted
技术标签:
【中文标题】Java /JPA |具有指定继承类型的查询【英文标题】:Java /JPA | Query with specified inherited type 【发布时间】:2011-06-20 12:47:58 【问题描述】:我正在对通用表“Sample”构建查询,并且我有几种类型从该表“SampleOne”、“SampleTwo”继承。 我需要这样的查询:
select s from Sample where s.type = :type
其中 type 是表的鉴别器值。是否有可能以任何方式(并避免创建特定于实体的查询,每个 SampleOne、SampleTwo ... 等一个)
我将非常感谢您对此主题的任何意见,
亲切的问候, P.
【问题讨论】:
【参考方案1】:在您的存储库中执行此操作
@Query("SELECT p FROM BaseUserEntity p where p.class=:discriminatorValue")
public List<BaseUserEntity> findByDiscriminatorValue(@Param("discriminatorValue") String discriminatorValue);
BaseUserEntity
是您的父实体
【讨论】:
【参考方案2】:在Hibernate 4.3.7还是要小心,因为TYPE()
的实现还是有问题,例如:
from SpoForeignPilot sfp where TYPE(sfp.partDocument) = :type
此查询不起作用,因为它错误地检查了 SpoForeignPilot
的类型而不是文档的类型。
您可以通过执行以下操作来解决此问题:
select sfp from SpoForeignPilot sfp join sfp.partDocument doc where TYPE(doc) = :type
【讨论】:
这对一个五年前的问题没有任何新意。 我只是想警告那些想要使用建议的解决方案(在 jpa 2 中使用 TYPE)进行更复杂查询的人,仍然存在问题(我在使用此线程中的解决方案时遇到了这个问题)。你是对的,问题中的查询没有暴露这个问题。 @WimDeRammelaere 经过数小时的挠头,您的回答帮助我找到了查询的问题。底线是,当我在 where 子句中使用 type 时,它在应用于连接时有效,但在路径表达式上使用时找不到任何结果。【参考方案3】:这是relevant section of the Java EE 6 tutorial:
抽象实体
一个抽象类 可以通过以下方式声明为实体 用
@Entity
装饰班级。 抽象实体就像混凝土 实体,但无法实例化。抽象实体只能被查询 像具体的实体。如果一个摘要 实体是查询的目标, 查询对所有具体的 抽象实体的子类:
@Entity
public abstract class Employee
@Id
protected Integer employeeId;
...
@Entity
public class FullTimeEmployee extends Employee
protected Integer salary;
...
@Entity
public class PartTimeEmployee extends Employee
protected Float hourlyWage;
如果我没看错,您的疑问:
select s from Sample where s.type = :type
如果type
是鉴别器列,则只应返回指定子类型的元素,因此您唯一要做的就是将结果列表转换为您请求的子类型。
【讨论】:
【参考方案4】:在 JPA 2.0 中,您可以使用 TYPE
表达式(虽然目前它不适用于 Hibernate 中的参数,请参阅 HHH-5282):
select s from Sample s where TYPE(s) = :type
类似的Hibernate特定表达式是.class
:
select s from Sample s where s.class = :type
【讨论】:
很抱歉就类似主题开始新的讨论,但是如果我提供一个抽象类作为 :type 是否有效? 根据hibernate.atlassian.net/browse/HHH-4881 这已在 Hibernate 4.0.0.CR5 中修复 一些缺失的信息:“TYPE”是一个“JPQL 特殊运算符”,包含参数元素名称,可能与简单的类名相比,这是一个更明确的示例(现在在休眠,无需解决方法)SELECT prj FROM Project prj WHERE TYPE(prj) = LargeProject
或使用 IN SELECT prj FROM Project prj WHERE TYPE(prj) IN ( MediumProject, LargeProject)
以上是关于Java /JPA |具有指定继承类型的查询的主要内容,如果未能解决你的问题,请参考以下文章
java 使用jpa参数+ TypedQuery进行示例搜索查询并继承常见的crud操作