【问题标题】:JPA fetch collection of subclassJPA 获取子类的集合
【发布时间】:2014-12-09 19:34:02
【问题描述】:

我有一个案例,我们有这样的继承策略(这是 jpa wiki 的一个例子,我们的真实例子是另一个商业案例:))

@Entity
@Inheritance
@DiscriminatorColumn(name="PROJ_TYPE")
@Table(name="PROJECT")
public abstract class Project {
  @Id
  private long id;
  ...
}
@Entity
@DiscriminatorValue("L")
public class LargeProject extends Project {
  @OneToMany
  private Set<Member> members;
}
@Entity
@DiscriminatorValue("S")
public class SmallProject extends Project {
}

我的数据库中有一堆项目,想一次获取所有项目,但这样做,我也想一次获取我的成员列表。 有没有办法用 jpql 做到这一点?我知道 TYPE 注释允许我查看类型,但我可以将它与 JOIN FETCH 结合使用吗?

我正在使用hibernate,但如果不需要,我不想降级回hibernate api

【问题讨论】:

  • 执行 entityManager.createQuery("from " + Project .class.getName()); 时会发生什么?它不获取成员列表吗?
  • 是的,但它不能让我决定是否要急切地获取它
  • @jelle 你想让他们急切地想,它让他们急切地想。问题是您希望它们通过单个执行的 SQL 查询立即被感染。不依赖 Hibernate API 是不可能的,因为 JPA 规范不强制实现 SQL 查询的执行方式。
  • 好的,谢谢你的遮阳篷。我已经怀疑只有 JPA 是不够的。什么是休眠解决方案?

标签: java hibernate jpa inheritance jpql


【解决方案1】:

JPA 和 Hibernate 不支持从子类中获取关联,除非该属性也存在于层次结构的最顶层成员中。但是根据这篇文章 (https://thorben-janssen.com/fetch-association-of-subclass/),您可以通过利用 hibernate 的 1 级缓存机制来解决这个限制。

在您的情况下,您将首先在一个单独的查询中获取Member 的所有实例,然后在Project 上执行您的查询,让LargeProject.members 加载Lazy。 hibernate 不会执行N + 1 SELECT,而是从缓存中获取它们。

【讨论】:

    【解决方案2】:

    有点晚了,但我找到了只使用 JPQL 的方法。 在你的情况下:

    SELECT p FROM Project p JOIN FETCH ((TREAT(p as LargeProject)).members)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-31
      • 1970-01-01
      • 2013-12-02
      • 1970-01-01
      • 2019-02-17
      相关资源
      最近更新 更多