【问题标题】:Java /JPA | Query with specified inherited typeJava /JPA |具有指定继承类型的查询
【发布时间】:2011-06-20 12:47:58
【问题描述】:

我正在对通用表“Sample”构建查询,并且我有几种类型从该表“SampleOne”、“SampleTwo”继承。 我需要这样的查询:

select s from Sample where s.type = :type

其中 type 是表的鉴别器值。是否有可能以任何方式(并避免创建特定于实体的查询,每个 SampleOne、SampleTwo ... 等一个)

我将非常感谢您对此主题的任何意见,

亲切的问候, P.

【问题讨论】:

    标签: java jpa entitymanager


    【解决方案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)
        猜你喜欢
        • 2015-03-06
        • 2011-01-09
        • 2015-08-31
        • 1970-01-01
        • 2023-03-13
        • 1970-01-01
        • 2019-12-12
        • 2016-01-29
        • 2022-11-23
        相关资源
        最近更新 更多