我正在使用OpenJPA和Joined继承策略(InheritanceType.JOINED - 所以对于超类中的所有字段都有一个表,而子类表只包含在子类中添加的任何字段的字段,以及一个引用返回到超类表)。 假设我有一个超类Person,以及一些子类:TypeAPerson,TypeBPerson等。当遇到如下查询时:
@NamedQuery(
name="Person.findByName",
query="SELECT p FROM Person p WHERE p.name = :name")
就我所熟悉而言,我不会得到一个Person实例,而是一个正确的子类实例。 如上所述here,为了实现这一点并获得正确的子类,OpenJPA将进行多个连接(每个子类一个)。这有很糟糕的表现,特别是如果我有很多子类。 我的问题是,如果有任何方法可以通过给JPA提示加入哪个表来避免这种情况?我首先想到的是使用Discriminator值。 OpenJPA支持使用具有连接策略的Discriminator,因此它应该能够从鉴别器值确定子类(因此是一个适当的连接表)?有没有办法实现这个目标? 是否有其他方法可以避免不必要的数据库连接?
答案 0 :(得分:1)
如果只需要单个子类的实体,那么避免多余连接的最佳方法是查询此子类。使用您的示例,它可能如下所示:
@NamedQuery(
name="Student.findByName",
query="SELECT s FROM Student s WHERE s.name = :name")
Student
是Person
的子类。当然,应该在适当的子类上定义命名查询。
无法两种方式 - 使用超类查询并仅连接单个子类表。持久性提供程序事先不知道结果,提示正确方向的唯一方法是搜索子类。
编辑:如果您不确定确切的子类,但可以限制可能的子类,可以使用带有IN子句的JPQL TYPE
关键字,如下所示:
queryString="SELECT p FROM Person p WHERE p.name = :name AND TYPE(p) IN (Student, Teacher)"
使用实体名称作为TYPE
的参数。 AFAIK,区分大小写。实际的鉴别器类型和值并不重要,因为您不是要查询它。类型解析由提供者完成。
然而,我不确定它是否会使提供程序限制必要的连接。如果您最终使用或对其进行基准测试,请告诉它是否确实如此。