Spring Data JPA and Angular: Hibernate In-Memory Pagination with Eager Fetching
0 reputation · 25 Jan 2026, 08:23 UTC
0 reputation · 25 Jan 2026, 08:23 UTC
JHipster applications utilize Spring Data JPA's Pageable interface to synchronize pagination between the Angular frontend and the Hibernate backend. This mechanism typically translates page and size parameters into SQL LIMIT and OFFSET clauses.
A technical conflict arises when entities are configured with FetchType.EAGER on collection associations. In these scenarios, Hibernate may struggle to apply pagination at the database level because the resulting join creates multiple rows for a single entity, potentially leading to the HHH000104 warning where pagination is performed in memory rather than via SQL.
For large datasets in a JHipster-generated environment, this shift to in-memory processing can significantly degrade performance and increase heap memory usage.
FetchType.EAGER for specific business requirements while ensuring database-level paginationHow does Hibernate handle the interaction between PageRequest and eager collection fetching in JHipster-generated repositories? What is the recommended strategy to prevent in-memory pagination without switching all associations to LAZY loading?
35275 reputation · 25 Jan 2026, 18:14 UTC
When a repository method receives a Pageable argument, Spring Data JPA delegates the pagination to Hibernate. If the underlying query includes an eager‑loaded collection association (e.g., @OneToMany(fetch = FetchType.EAGER)), Hibernate must join the parent table to the collection table. This join produces multiple rows for a single parent entity. Hibernate then applies the LIMIT/OFFSET after the join, which often results in the warning HHH000104: firstResult/maxResults specified with collection fetch; applying in memory!. The rows are fetched from the database, duplicated by the join, and the pagination is performed in Java memory.
LIMIT/OFFSET clause is present.public interface UserSummary {
Long getId();
String getLogin();
String getFirstName();
String getLastName();
}
@Repository
public interface UserRepository extends JpaRepository {
Page findAllBy(Pageable pageable);
}
@EntityGraph that fetches the collection lazily and then initializes it after the page is loaded:@EntityGraph(attributePaths = {"orders"}, type = EntityGraph.EntityGraphType.LOAD)
Page findAllWithOrders(Pageable pageable);
DISTINCT and applies pagination before the join:@Query("select distinct u from User u left join fetch u orders where ...")
Page findAllWithOrdersFetchJoin(Pageable pageable);
application.yml:spring:
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
limit and offset without the HHH000104 warning.Are you already using a custom JPQL/HQL query with explicit fetch joins in your repository method? If yes, the solution may require adjusting the query’s DISTINCT placement or switching to a DTO projection instead of an entity graph.
Use comments to ask for clarification. Post a solution as an answer.
6,620 reputation · 25 Jan 2026, 09:22 UTC
To build on the suggested strategies, it is important to note that FetchType.EAGER on collections often creates a Cartesian product if multiple collections are fetched simultaneously. This exacerbates the memory pressure during the in-memory pagination described by the HHH000104 warning.
For cases where DTOs are not viable, a "two-step" fetch is a reliable alternative to maintain database-level pagination:
LIMIT and OFFSET are applied correctly by the database.JOIN FETCH or @EntityGraph to retrieve the full entities and their collections.This approach avoids the HHH000104 warning entirely by separating the pagination logic from the collection joining logic. You can verify if this is necessary by enabling spring.jpa.show-sql=true; if the generated SQL lacks a LIMIT clause despite a Pageable argument, Hibernate has reverted to in-memory processing.