本文介绍了从类层次结构中仅检索超类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况:

@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语句:

I have a JPA Select statement like this:

SELECT a FROM Animal a;

我正在使用Hibernate 3.3.1

I'm using Hibernate 3.3.1

如我所见,该框架使用左外部联接检索AnimalDog的实例.

As I can see the framework retrieves instances of Animal and also of Dog using a left outer join.

有没有办法只选择部件" Animal?我的意思是,以前的Select将获得所有Animal,只有Animal而不是Dog的所有Dog.

Is there a way to Select only the "part" Animal? I mean, the previous Select will get all the Animals, those that are only Animals but not Dogs and those that are Dogs.

我都想要它们,但是对于Dog s,我只想检索它们的动物部分".

I want them all, but in the case of Dogs I want to only retrieve the "Animal part" of them.

我找到了@org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT)但正如我所见,这仅在Animal不是@Entity时有效.

I found the @org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT)but as I could see this only works if Animal isn't an @Entity.

非常感谢.

推荐答案

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

Short answer: The behaviour you describe complies with JPA standard. There is no JPA standard way to restrict the JPA provider to retrieve only the superclass.

提供商可以选择查询实现逻辑来实现功能,一致性和安全性.表现.只要它尊重您的实体注释并在查询中返回所请求的信息,那么一切都很好.可以将与Dog的外部连接视为您不关心的私有实现细节.提供者已对外部联接进行了编码,以帮助提高性能和一致性.

The provider can choose query implementation logic to achieve functionality, consistency & performance. As long as it respects your entity annotations and returns the requested information in the query all is good. Think of the outer join to Dog as private implementation detail that should not concern you. The provider has coded an outer join to assist performance and consistency.

考虑:

  • JPA被定义为在Java对象实体而不是表上工作
  • 您的实体层次结构动物的根不是抽象的,因此您可以创建一个实例并将其持久化.
  • 您具有Animal @DescriminatorColumn和@DescriminatorType的默认值-因此Animal表中将添加一个带有名称"DTYPE"和类型"some String type"的鉴别符列.您具有@DescriminatorValue的默认值-等于实体名称:动物.因此,当您创建此实体时,Animal.DTYPE column =动物".
  • 实体狗具有超类动物.默认值还用于其@DescriminatorValue-狗.因此,创建此实体时Animal.DTYPE column ="Dog".
  • Java类限制可确保每当Dog对象存在时,相应的Animal超类对象也将存在.
  • 通常,当您将实体动物加载到JPA持久性上下文中且其@DescriminatorValue(值存储在DTYPE列中)="Dog"时,将Dog对象加载到PC中以保持一致性非常有用.即使JPA标准没有要求.
  • 不能将继承关系指定为EAGER或LAZY(如基本类型字段或实体关系字段).如果您需要读取/更新狗的属性,并且没有加载Dog类,该怎么办?运行一个单独的查询来重新加载它?这会极大地损害一致性和性能.
  • 对性能的主要关注是发送到DB的单独SQL命令的总数.
    就花费的时间而言:使用动物表进行的查询仅比将动物外部连接到狗的查询稍快(10微秒???),但比两个单独的查询(一个用于动物,一个用于狗)要快得多.
  • JPA is defined to work on java object Entities not tables
  • Root of your Entity hierarchy, Animal, is not abstract, so you can create an instance and persist it.
  • You have a default value for Animal @DescriminatorColumn and @DescriminatorType - so Animal table will have a discriminator column added with name "DTYPE" and type "some String type". You have a default value for @DescriminatorValue - will be equal to the Entity name: Animal. So Animal.DTYPE column = "Animal" when you create this entity.
  • The Entity Dog has a superclass Animal. The default value is also used for its @DescriminatorValue - Dog. So Animal.DTYPE column = "Dog" when you create this entity.
  • Java class restrictions ensure that whenever a Dog object exists a corresponding Animal superclass object also exists.
  • Very often, when you have an Entity Animal loaded into JPA persistence context, with a @DescriminatorValue (value stored in DTYPE column) = "Dog", then it is very useful to have Dog object loaded into PC for consistency. Even though it is not required by the JPA standard.
  • The inheritance relationship cannot be specified to be EAGER or LAZY (like a basic type field or entity relationship field). If you needed to read/update dog properties and the Dog class was not loaded what would you do? Run a separate query to reload it? This would hurt consistency and performance greatly.
  • The main concern for performance is the total number of separate SQL commands sent to the DB.
    In terms of time taken:query with animal table is only slightly faster (10s of microseconds???) than query with animal outer joined to dog, but is much faster than two separate queries (one for animal and one for dog)

这篇关于从类层次结构中仅检索超类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 14:50