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

时间:2012-11-01 22:37:32

标签: 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;
    }
        .
        .
        .
}

并作为子类:

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

    private static final long serialVersionUID = -7341592543130659641L;
        .
        .
        .
}

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

SELECT a FROM Animal a;

我正在使用Hibernate 3.3.1

我可以看到框架使用左外连接检索AnimalDog的实例。

有没有办法只选择“部分”Animal?我的意思是,之前的Select将获得所有Animal s,仅Animal但不是Dog s的DogDog s。

我想要所有这些,但在@org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT) s的情况下,我只想检索它们的“动物部分”。

我找到了@Entity 但正如我所看到的,只有当Animal不是{{1}}时才有效。

非常感谢。

2 个答案:

答案 0 :(得分:2)

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

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

考虑:

  • JPA被定义为处理java对象实体而不是表
  • 您的实体层次结构Root的根不是抽象的,因此您可以创建一个实例并将其保留。
  • 您有一个Animal @DescriminatorColumn和@DescriminatorType的默认值 - 因此Animal表将添加一个名为“DTYPE”的标识符列,并键入“some String type”。您有@DescriminatorValue的默认值 - 将等于实体名称:Animal。因此,当您创建此实体时,Animal.DTYPE column =“Animal”。
  • 实体狗有一个超类动物。默认值也用于其@DescriminatorValue - Dog。因此,当您创建此实体时,Animal.DTYPE column =“Dog”。
  • Java类限制确保每当Dog对象存在时,也存在相应的Animal超类对象。
  • 通常,当您将实体动物加载到JPA持久性上下文中时,使用@DescriminatorValue(值存储在DTYPE列中)=“Dog”,将Dog对象加载到PC中以保持一致性非常有用。即使JPA标准不要求它。
  • 继承关系不能指定为EAGER或LAZY(如基本类型字段或实体关系字段)。如果你需要读取/更新狗属性并且没有加载Dog类,你会怎么做?运行单独的查询来重新加载它?这会大大损害一致性和性能。
  • 性能的主要关注点是发送到DB的单独SQL命令的总数 在时间方面: 使用动物表查询只比动物外部加入狗的查询稍快(10秒微秒???),但比两个单独的查询(一个用于动物,一个用于狗)要快得多。

答案 1 :(得分:0)

实际上,有一种方法可以获得超类:您只需要使用JPA的本机查询。就我而言,我正在使用JPA存储库。因此,它会是这样的:

@Query(value = "SELECT * FROM animal", nativeQuery = true)
List<Resource> findAllAnimal();

标志nativeQuery为true允许在数据库上运行本机SQL。

如果您使用的是实体管理器,请查看以下内容:https://www.thoughts-on-java.org/jpa-native-queries/