When you load an entity (like User, Order, etc.), related entities (like roles, addresses, etc.) are not fetched immediately if they are marked as LAZY. This can lead to:
- N+1 select problem (lots of tiny SQL queries),
- Or
LazyInitializationExceptionwhen accessing a lazy field outside the transaction.
@EntityGraph lets you tell JPA exactly which relationships to fetch eagerly in a specific query, without changing your entity mappings.
“I want to fetch User along with their roles, but I don’t want to mark roles as EAGER in the entity itself. Just for this query, fetch it eagerly.”
Suppose you have this:
@Entity
public class User {
@Id
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Role role;
}Now let’s say you want to fetch the User with its Role eagerly in one query.
@Query("select u from User u join fetch u.role where u.name = ?1")
User findByName(String name);Problem: You must write custom JPQL, and it always fetches role.
@EntityGraph(attributePaths = "role")
User findByName(String name);Much cleaner! This tells Spring Data JPA:
When running this method, join fetch the
roletoo.
@EntityGraph(attributePaths = {"role", "address", "company"})
User findByName(String name);@Query("select u from User u where u.name = ?1")
@EntityGraph(attributePaths = "role")
User findByName(String name);- You don’t need to change
LAZYtoEAGERin your entities. - It helps avoid performance problems (like N+1 queries).
- You can even define named entity graphs in the entity class and refer to them.
| Annotation | Purpose |
|---|---|
@EntityGraph |
Fetch specific relationships eagerly in a query |
attributePaths |
List of fields (relationships) to fetch eagerly |
| Works with | Repository methods, @Query, or both |