【问题标题】:OpenJPA joined inheritance - avoid database joinsOpenJPA 加入继承 - 避免数据库连接
【发布时间】:2013-01-16 10:32:07
【问题描述】:

我正在使用带有 Joined 继承策略的 OpenJPA(InheritanceType.JOINED - 因此超类中的所有字段都有一个表,而子类表只包含在子类中添加的任何内容的字段,以及返回的引用到超类表)。 假设我有一个超类 Person 和许多子类:TypeAPerson、TypeBPerson 等。当有如下查询时:

@NamedQuery(
name="Person.findByName", 
query="SELECT p FROM Person p WHERE p.name = :name")

据我所知,我不会得到 Person 实例,而是正确的子类实​​例。 如here 所述,为了实现这一点并获得正确的子类,OpenJPA 将进行多个连接(每个子类一个连接)。这具有相当糟糕的性能,特别是如果我有很多子类。 我的问题是,是否有任何方法可以通过提示 JPA 加入哪个表来避免这种情况?我想到的第一件事是使用鉴别器值。 OpenJPA 支持使用加入策略的鉴别器,所以它应该能够从鉴别器值中确定一个子类(以及一个合适的加入表)?有没有办法做到这一点? 有没有其他方法可以避免不必要的数据库连接?

【问题讨论】:

  • 我不是专家,但 DiscriminatorColumn 可能是解决方案。查看 Joined Inheritance 和 DiscriminatorColumn 用法的完整示例here

标签: inheritance jpa discriminator


【解决方案1】:

如果您只需要单个子类的实体,那么避免多余连接的最佳方法是查询该子类。使用您的示例,它可能如下所示:

@NamedQuery(
name="Student.findByName", 
query="SELECT s FROM Student s WHERE s.name = :name")

StudentPerson 的子类。当然,命名查询应该在适当的子类上定义。

没有办法两者兼得 - 使用超类查询并仅连接单个子类表。持久性提供者事先不知道结果,提示正确方向的唯一方法是搜索子类。

编辑:如果您不确定确切的子类,但可以限制可能的子类,您可以使用带有 IN 子句的 JPQL TYPE 关键字,如下所示:

queryString="SELECT p FROM Person p WHERE p.name = :name AND TYPE(p) IN (Student, Teacher)"

使用实体名称作为TYPE 的参数。 AFAIK,它区分大小写。实际的鉴别器类型和值并不重要,因为您没有查询它。类型解析由提供者完成。

但是,我不确定它是否会使提供者限制必要的加入。如果您最终使用它或对其进行基准测试,请告诉它是否这样做。

【讨论】:

  • 感谢您的回答。不幸的是,这个选项不适合我的情况。我有一种情况,我知道 Person.Id,但我事先不知道它的类型,所以我无法查询特定的子类。这就是为什么我询问鉴别器的原因——我现在能想到的唯一方法是进行两个查询:选择一个人,然后根据鉴别器的值,查询正确的子类。但是JPA不支持这似乎很奇怪,因为鉴别器用于解析子类。
  • @Ane - 我明白了。使用 TYPE 关键字还有一种我之前没有想到的可能性。请查看编辑。
猜你喜欢
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 2012-11-13
  • 2019-02-04
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多