Difference between FetchType LAZY and EAGER in Java Persistence API?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
In Java Persistence API (JPA), entity relationships are a core concept, and how these relationships are fetched—either eagerly or lazily—significantly impacts application performance and behavior. FetchType.LAZY and FetchType.EAGER are the two primary fetching strategies in JPA, and choosing the right one is crucial for efficient data access.
FetchType.EAGER
With FetchType.EAGER, JPA loads the associated entities as soon as the parent entity is loaded. This is the simplest form of fetching as it doesn't require any additional configuration or thought once set. It eliminates the need for the application to explicitly fetch parts of the graph later.
Example: Consider an Order entity with multiple Product entities.
Here, whenever an Order is fetched from the database, all associated Products are also automatically fetched, regardless of whether they are used or not.
FetchType.LAZY
FetchType.LAZY, on the other hand, means that the associated entities are loaded only on demand. This can lead to improved performance, especially if the associated entities are rarely accessed. Lazy loading uses proxy objects or collections that fetch the actual entities when accessed for the first time.
Example:
In this example, Product entities are not fetched with the Order. They are fetched only when the application accesses the products collection.
Key Differences
The core difference between these two approaches lies in when the associated data is loaded from the database. Eager fetching loads all data upfront, which can be beneficial when you know that you will use the data and it saves additional database calls later. However, it can lead to significant performance drawbacks if not used carefully, such as increased memory usage and slower query performance due to loading unnecessary data.
Lazy loading, while more efficient in terms of resource use, can lead to the infamous "N+1 selects problem." This problem occurs when the application needs to access each associated entity individually, thus creating a new database call for each access.
Considerations and Best Practices
- Use
FetchType.LAZYby default: Start with lazy loading and switch to eager only if profiling dictates. It generally leads to better overall performance. - Profile your application: Always measure the impact of fetching strategies on your application’s performance.
- Beware of the context: In some contexts, such as within transaction-bound contexts or read-only operations, lazy loading can be less efficient due to repeated opening and closing of session/transaction.
- Utilize fetching strategies: Consider utilizing batch fetching, fetch joins, or sub-selects to optimize lazy loading.
Summary Table
| Attribute | FetchType.LAZY | FetchType.EAGER |
| Loading Time | On Access | On Initial Loading |
| Default Scenario | Recommended in most scenarios | Should be used cautiously |
| Memory and Resource Utilization | Generally lower | Higher, as all related data is loaded |
| Suitability | Best for data that is not always needed | Good when related data is always needed |
| Risk of N+1 Problem | Higher (but manageable with strategies) | None |
In conclusion, understanding the trade-offs between eager and lazy fetching in JPA is critical for developing high-performing Java applications. While lazy loading can be more complex to handle due to issues like the "N+1 selects problem," it often results in more scalable and efficient applications when used correctly. Conversely, eager fetching is straightforward but can lead to unnecessary data retrieval and increased memory usage. Designing your application with the appropriate fetching strategy in mind will lead to a more balanced and performant application.
Related reading
- Difference between filter and filter_by in SQLAlchemy
- Difference between findBy and findOneBy in Spring data JPA
- Difference between Key, Primary Key, Unique Key and Index in MySQL
- Difference Between One-to-Many, Many-to-One and Many-to-Many?
- Difference between IP multicast and Basic multicast(B-Multicast)
- Difference between NodePort and LoadBalancer?
- Difference between on-heap and off-heap
- Difference between On and Ologn - which is better and what exactly is Ologn?

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.