0
0
SpringbootComparisonBeginner · 4 min read

Lazy vs Eager Fetch in JPA: Key Differences and When to Use Each

In JPA, Lazy fetch delays loading related entities until they are accessed, while Eager fetch loads all related entities immediately with the main entity. Lazy fetch improves performance by loading data only when needed, whereas eager fetch simplifies access but can cause unnecessary data loading.
⚖️

Quick Comparison

This table summarizes the main differences between Lazy and Eager fetch types in JPA.

FactorLazy FetchEager Fetch
Loading TimeLoads related data only when accessedLoads related data immediately with main entity
PerformanceBetter for large or optional dataCan cause performance issues if data is large
Use CaseWhen related data is not always neededWhen related data is always needed
Proxy ObjectsUses proxies to delay loadingNo proxies, direct loading
RiskCan cause LazyInitializationException if accessed outside sessionNo such risk, data always available
ComplexityRequires careful session managementSimpler to use but less efficient
⚖️

Key Differences

Lazy fetch means JPA will not load the related entities from the database until you actually try to use them in your code. It uses proxy objects as placeholders. This approach saves resources by avoiding unnecessary data loading, especially useful when related data is large or rarely needed.

In contrast, Eager fetch loads all related entities immediately when the main entity is fetched. This makes accessing related data straightforward without extra queries later, but it can slow down performance if the related data is large or not always required.

One important difference is that Lazy fetch can cause a LazyInitializationException if you try to access the related data outside the persistence context (like after the database session is closed). Eager fetch avoids this by loading everything upfront, but at the cost of potentially loading unnecessary data.

⚖️

Code Comparison

Example of Lazy fetch in a JPA entity relationship:

java
import jakarta.persistence.*;
import java.util.List;

@Entity
public class Author {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "author")
    private List<Book> books;

    // getters and setters
}
Output
Author entity loads without books; books load only when accessed.
↔️

Eager Fetch Equivalent

Example of Eager fetch for the same relationship:

java
import jakarta.persistence.*;
import java.util.List;

@Entity
public class Author {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "author")
    private List<Book> books;

    // getters and setters
}
Output
Author entity loads with all books immediately.
🎯

When to Use Which

Choose Lazy fetch when related data is large, optional, or rarely needed to improve performance and reduce memory use. It is ideal for complex applications where loading everything upfront would be costly.

Choose Eager fetch when related data is always needed together with the main entity, and simplicity is more important than performance. This avoids extra queries and session management issues.

In general, prefer Lazy fetch for better control and efficiency, but use Eager fetch when you are sure the related data is always required immediately.

Key Takeaways

Lazy fetch delays loading related data until accessed, saving resources.
Eager fetch loads all related data immediately, simplifying access but may hurt performance.
Lazy fetch can cause errors if accessed outside a session; eager fetch avoids this.
Use lazy fetch for optional or large data, eager fetch when related data is always needed.
Choosing the right fetch type improves application performance and resource use.