仅从类层次结构中检索超类

Gus*_*ava 5 java hibernate jpa class-hierarchy

我有一个场景如下:

@Entity
@Table(name = "ANIMAL")
@Inheritance(strategy = InheritanceType.JOINED)

public class Animal implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "S_ANIMAL")
    @SequenceGenerator(name = "S_ANIMAL", sequenceName = "S_ANIMAL", allocationSize = 1)
    public int getNumero() {
        return numero;
    }

    public void setNumero(int numero) {
        this.numero = numero;
    }
        .
        .
        .
}
Run Code Online (Sandbox Code Playgroud)

并作为子类:

@Entity
@Table(name = "DOG")
public class Dog extends Animal {

    private static final long serialVersionUID = -7341592543130659641L;
        .
        .
        .
}
Run Code Online (Sandbox Code Playgroud)

我有一个像这样的 JPA Select 语句:

SELECT a FROM Animal a;
Run Code Online (Sandbox Code Playgroud)

我正在使用休眠 3.3.1

正如我所看到的,框架检索使用左外连接的Animal实例Dog

有没有办法只选择“部分” Animal?我的意思是,前一个Select将得到所有Animals,那些只有Animals 但不是Dogs 的以及那些是Dogs 的。

我想要它们全部,但在 s 的情况下,Dog我只想检索它们的“动物部分”。

我找到了,@org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT) 但据我所知,只有当 Animal 不是@Entity.

多谢。

Gle*_*est 3

简短回答:您描述的行为符合 JPA 标准。没有 JPA 标准方法来限制 JPA 提供程序仅检索超类。

提供者可以选择查询实现逻辑来实现功能、一致性和性能。只要它尊重您的实体注释并在查询中返回所请求的信息,一切都很好。将 Dog 的外部连接视为私有实现细节,您不应该关心它。提供者已编写了外部联接的代码以提高性能和一致性。

考虑:

  • JPA 被定义为适用于 java 对象实体而不是表
  • 实体层次结构的根 Animal 不是抽象的,因此您可以创建一个实例并保留它。
  • 您有 Animal @DecriminatorColumn 和 @DecriminatorType 的默认值 - 因此 Animal 表将添加一个名称为“DTYPE”且类型为“某些字符串类型”的鉴别器列。@DecriminatorValue 有一个默认值 - 将等于实体名称:Animal。因此,当您创建此实体时,Animal.DTYPE 列 =“动物”。
  • 实体狗有一个超类动物。默认值也用于其 @DecriminatorValue - Dog。因此,当您创建此实体时,Animal.DTYPE 列 =“Dog”。
  • Java 类限制确保每当 Dog 对象存在时,相应的 Animal 超类对象也存在。
  • 通常,当您将实体动物加载到 JPA 持久性上下文中,并使用 @DecriminatorValue(存储在 DTYPE 列中的值)=“Dog”时,将 Dog 对象加载到 PC 中以保持一致性非常有用。尽管 JPA 标准不要求这样做。
  • 继承关系不能指定为 EAGER 或 LAZY(如基本类型字段或实体关系字段)。如果您需要读取/更新狗属性并且 Dog 类未加载,您会做什么?运行单独的查询来重新加载它?这会极大地损害一致性和性能。
  • 对性能的主要关注点是发送到数据库的单独 SQL 命令的总数。
    就所用时间而言:使用动物表进行查询仅比使用动物外部连接到狗的查询稍快一些(10 微秒???),但比两个单独的查询(一个用于动物,一个用于狗)快得多