繁体   English   中英

Hibernate n + 1选择多个表层次结构

[英]Hibernate n+1 select with multiple table hierarchy

我有下一个班级结构

@Entity
@Table(name = "Company")
public class Company {
   @Id
   @GeneratedValue
   private Long id;

   @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
   @JoinColumn(name = "CompanyId")
   @Fetch(FetchMode.SUBSELECT)
   private Set<Departement> departements;
}

@Entity
@Table(name = "Departement")
public class Departement {
   @Id
   @GeneratedValue
   private Long id;

   @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
   @JoinColumn(name = "DepartementId")
   @Fetch(FetchMode.SUBSELECT)
   private Set<Employee> employees;
}

@Entity
@Table(name = "Employee")
public class Employee {
   @Id
   @GeneratedValue
   private Long id;

  // other fields and methods
}

在应用程序启动时,我需要使用已初始化的内部集合来获取所有公司。 我的数据库足够大(公司表中有1,5 M行)。 我需要解决n + 1选择问题以加速数据检索。 带有fetch join的解决方案在我的情况下不起作用,因为生成的sql查询返回了大量的数据集,即使我像这样使用滚动

Query query = session.createQuery(query);
query.setReadOnly(true);
// MIN_VALUE gives hint to JDBC driver to stream results
query.setFetchSize(Integer.MIN_VALUE);
ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);

它仍然消耗我的所有RAM,因为我无法刷新会话或驱逐检索到的实体。

另一种方法是使用子选择,但是当我这样做时

@SuppressWarnings("unchecked")
List<Company> companies = session.createQuery("from Company").list();

for (Company c : companies) {
    for (Departement d : c.getDepartements()) {
        d.getEmployees();
    }
}

hibernate只生成2个查询:一个用于Company表

select ... from Company company

和另一个部门表

select ... from Departement departemen0_ 
where departemen0_.CompanyId in (select company0_.id from Company company0_)

我仍然需要分别从Departement类初始化员工集合。

有没有办法检索所有3个子选择表? 或者可能有另一种方法来检索给定结构的大量数据?

您的代码只生成两个查询(对于公司和部门),因为您的Employee查询代码(第三个和所需的查询代码)不是延迟获取的。 所以,只需改变:

d.getEmployees();

至:

d.getEmployees().size();

如果您正在处理这些数据, SUBSELECT似乎是适合您的策略

  • JOIN:避免N + 1查询的主要问题,但它可以检索重复的数据。
  • SUBSELECT:也避免N + 1并且不重复数据,但它将相关类型的所有实体加载到内存中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM