How to fetch FetchType.LAZY associations with JPA and Hibernate in a Spring Controller
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Java Persistence API (JPA) and Hibernate are powerful tools for database operations within Java applications. Fetching associations efficiently is crucial for the performance of your application, and Hibernate provides two fetch types to choose from: EAGER and LAZY. While EAGER loading is straightforward, FetchType.LAZY allows for deferred loading of associated entities, which can lead to performance improvements by avoiding unnecessary data retrieval. This article explains how to properly fetch FetchType.LAZY associations within a Spring Controller by leveraging JPA and Hibernate features.
Understanding FetchType.LAZY
In JPA, FetchType.LAZY indicates that the associated entities or collections should be loaded lazily, i.e., not fetched from the database until they are explicitly accessed. This helps optimize performance by reducing the number of queries and the amount of data transferred.
Example Entity Setup
Consider a simple example with two entities: Author and Book. An Author can have many Books.
In the Author entity, the books collection is marked with FetchType.LAZY. By default, many-to-one associations (Book.author) are eagerly loaded in Hibernate unless specified otherwise.
Fetching Lazy Associations in a Spring Controller
Fetching lazy associations (like books in the previous example) can lead to LazyInitializationException if accessed outside of a transaction context. To handle this properly in a Spring application, you can use several approaches.
1. Use Open Session in View Pattern
Spring's Open Session in View (OSIV) pattern keeps the Hibernate session open during the duration of a web request, allowing lazy loading to occur within a single transaction. To enable this, Spring Boot includes an OpenSessionInViewFilter by default.
2. Using @Transactional Annotation
Another approach is to use the @Transactional annotation on service layer methods to ensure that lazy loading occurs within a transaction boundary.
3. Explicitly Fetch with JPQL or Criteria API
When you want more control over data retrieval, you can explicitly fetch associations using JPQL or Hibernate Criteria API.
4. Use DTO Projections
Instead of loading the full entity graph with potentially unnecessary information, use Data Transfer Objects (DTOs) to project only necessary data.
Summary Table
| Approach | Description | Pros | Cons |
| Open Session in View | Keeps session open for the entire web request | Simple to implement | May lead to lazy loading in views |
@Transactional | Ensures lazy loading within a transaction in the service layer | Clear transaction boundaries | Only solves part of the problem if not careful |
| JPQL/Criteria API | Uses custom queries to fetch all required data eagerly | Full control over queries | More complex queries |
| DTO Projections | Loads only necessary data into custom objects | Efficient data retrieval | Requires additional DTO classes |
Conclusion
Fetching lazy associations effectively in JPA and Hibernate requires a deliberate choice of strategy based on your application requirements. While leveraging Spring's OSIV is easy, fine-grained control through transactions, queries, or DTOs can result in more efficient database operations. Understanding the implications of each approach can help in optimizing your application’s performance.
Related reading
- How to fetch offset id while consuming Kafka from Spark, save it in Cassandra and use it to restart Kafka?
- how to filter cassandra query by a field in user defined type
- How to filter Pandas dataframe using 'in' and 'not in' like in SQL
- How to filter Pandas dataframe using 'in' and 'not in' like in SQL
- How to find files that match a wildcard string in Java?
- How to find out the currently logged-in user in Spring Boot?
- How to find a columns set for a primary key candidate in CSV file?
- How to find a substring in a field in Mongodb

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.