将所选字段集限制为目标子类的字段集

Limit the set of selected fields to those of the target subclass

我正在使用单一 table 继承,一个父实体:

@Entity
@Table(name = "parent")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public class Parent {
  // ...
}

和两个子实体:

@Entity
@DiscriminatorValue("child1")
public class Child1 extends Parent {
  @Column(name = "child1_property")
  private Integer child1Property;
  // ...
}
@Entity
@DiscriminatorValue("child2")
public class Child2 extends Parent {
  @Column(name = "child2_property")
  private Integer child2Property;
  // ...
}

现在,如果我直接从 Child1 实体查询 (HQL):

from Child1

它将生成一个 SQL,其中 select 只有来自 Parent 实体的列加上 Child1 实体。如果我 select 从 Parent 实体使用 where type='child1'

from Parent p where type(p)='child1'

它将 return 仅 Child1 个实体,但 SQL 查询 select 来自 ParentChild1Child2。是否有可能从 Parent 实体查询使用鉴别器列(即仅限于 Child1 实体)并获得特定的 SQL 查询,即仅 select 列来自 ParentChild1.

投影似乎有效:

SELECT new fully.qualified.name.of.Child1(p.id, p.name, p.child1Property)
  FROM Parent p
 WHERE TYPE(p) = 'child1'

生产

    select
        parent0_.id as col_0_0_,
        parent0_.name as col_1_0_,
        parent0_.child1_property as col_2_0_ 
    from
        parent parent0_ 
    where
        parent0_.type='child1'

Hibernate 用户指南excerpt:

There is a particular expression type that is only valid in the select clause. Hibernate calls this "dynamic instantiation". JPQL supports some of that feature and calls it a "constructor expression".

So rather than dealing with the Object[] (again, see Hibernate Query API) here, we are wrapping the values in a type-safe Java object that will be returned as the results of the query.

...

The projection class must be fully qualified in the entity query, and it must define a matching constructor.

The class here need not be mapped. It can be a DTO class.

If it does represent an entity, the resulting instances are returned in the NEW state (not managed!).

不过,我只是 SELECT c FROM Child1 c。我真的很惊讶 Hibernate 没有抱怨实体 Parent.

缺少属性 child1Property