I have next class structure
@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
}
On the application startup I need to fetch all the companies with the initialized internal collections. My database is big enough (1,5 M rows in the Company table). I need to solve n+1 selection issue to speed up data retrieval. The solution with fetch joins does not work in my case because the generated sql query returns enormous data set and even if I use scroll like this
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);
it still consumes all my RAM because I cannot flush session or evict retrieved entities.
Another approach is to use subselects but when I do
@SuppressWarnings("unchecked")
List<Company> companies = session.createQuery("from Company").list();
for (Company c : companies) {
for (Departement d : c.getDepartements()) {
d.getEmployees();
}
}
hibernate generates only 2 queries: one for Company table
select ... from Company company
and another for Department table
select ... from Departement departemen0_
where departemen0_.CompanyId in (select company0_.id from Company company0_)
and I still have to initialize employees collection from the Departement class separately.
Is there any way to retrieve all 3 tables with subselects? Or may be there is another way to retrieve big amount of data with the given structure?