1

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

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

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

4

1 回答 1

1

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

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

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

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

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

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

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

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

于 2013-01-16T14:17:44.667 回答