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 |具有指定继承类型的查询的主要内容,如果未能解决你的问题,请参考以下文章

如何解决从另一个实体(JPA)继承的实体的“未指定主键”?

java 使用jpa参数+ TypedQuery进行示例搜索查询并继承常见的crud操作

Spring Data JPA中使用QueryDSL进行查询

用户类型、jpa 和 Play 的继承问题!框架

JPA实体继承实体的映射策略

JPA实体继承实体的映射策略