Clean ⢠Professional
@EntityGraph in JPAIn JPA, fetching strategies (EAGER vs LAZY) control how related entities are loaded. Sometimes, fetching related entities lazily can cause the N+1 query problem, which severely affects performance.
@EntityGraph is a feature in Spring Data JPA that allows you to override default fetch strategies at runtime, letting you fetch associations eagerly without changing entity mappings.
@EntityGraph?Key Benefit: Fetch associations efficiently without changing @OneToMany or @ManyToOne fetch types in entities.
Basic Syntax
@EntityGraph(attributePaths = {"orders", "profile"})
List<User>findAll();
Explanation:
attributePaths ā specifies related entities to fetch eagerly.FetchType.LAZY.@EntityGraph is Important@EntityGraph allows developers to control fetching at the query level.The type attribute in @EntityGraph determines how unspecified attributes are fetched:
| Type | Behavior |
|---|---|
| FETCH (default) | Attributes in the graph are fetched eagerly; unspecified attributes are treated as LAZY, ignoring entity mappings. |
| LOAD | Attributes in the graph are fetched eagerly; unspecified attributes follow their default fetch type defined in the entity. |
Example:
@EntityGraph(attributePaths = {"orders"}, type = EntityGraph.EntityGraphType.LOAD)
List<User>findAll();
orders are eagerly fetched.attributePaths)Fetch associations for a specific query:
@Repository
publicinterfacePostRepositoryextendsJpaRepository<Post, Long> {
@EntityGraph(attributePaths = {"author", "comments"})
List<Post>findAllWithAuthorAndComments();
}
ā
Fetches Post with author and comments in one query, preventing N+1 queries.
Step 1: Define Named Graph in Entity
@Entity
@NamedEntityGraph(
name = "Post.author",
attributeNodes = @NamedAttributeNode("author")
)
publicclassPost {
@Id
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY)
private Author author;
// Getters and setters
}
Step 2: Reference in Repository
@Repository
publicinterfacePostRepositoryextendsJpaRepository<Post, Long> {
@EntityGraph(value = "Post.author")
Optional<Post>findById(Long id);
}
@EntityGraph(attributePaths = {"orders", "profile"})
List<User>findByActiveTrue();
@Query("SELECT u FROM User u WHERE u.active = true")
@EntityGraph(attributePaths = {"orders"})
List<User>findActiveUsers();
@EntityGraph with JPQL.@EntityGraph(attributePaths = {"orders"})
Page<User>findByActiveTrue(Pageable pageable);JOIN FETCH with pagination, which may fail in JPQL.@EntityGraphSingle-valued Associations : Associations where an entity references only one other entity.
Example
@Entity
publicclassOrder {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private User user;
@OneToOne(fetch = FetchType.LAZY)
private Payment payment;
}
Characteristics:
@EntityGraph.attributePaths.Collection-valued Associations : Associations where an entity references a collection of other entities.
Example
@Entity
publicclassUser {
@Id
private Long id;
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Order> orders;
@ManyToMany(fetch = FetchType.LAZY)
private List<Role> roles;
}
Characteristics:
@EntityGraph allows selective eager fetching, reducing N+1 queries.| Feature | Single-valued | Collection-valued |
|---|---|---|
| Examples | @ManyToOne, @OneToOne | @OneToMany, @ManyToMany |
| SQL Impact | Simple JOIN | Potential Cartesian product |
| Pagination | Easy | Complex if multiple collections |
| Performance Risk | Low | High for large collections |
Use with @EntityGraph | Safe | Use selectively |
@EntityGraph vs JOIN FETCH| Feature | @EntityGraph | JOIN FETCH |
|---|---|---|
| Reusability | Can define named entity graphs and reuse across multiple repository methods | Each JOIN FETCH is tied to a specific query and cannot be reused |
| Overrides LAZY | Yes, can fetch lazy associations eagerly without changing entity mappings | Yes, but only for that specific JPQL query |
| JPQL query requirement | Optional ā can be used with method name queries | Required ā must be specified in JPQL or Criteria query |
| Code readability | Cleaner and easier to maintain, especially for multiple associations | Queries become longer and harder to read with multiple joins |
| Dynamic association selection | Can specify which associations to fetch at the repository method level | Associations are fixed in the JPQL query and cannot be changed dynamically |
@EntityGraph with pagination for large datasets.attributePaths for simple, single-use queries.@EntityGraph(attributePaths = {"orders"})
Page<User>findByActiveTrue(Pageable pageable);
orders while supporting pagination.@EntityGraph allows dynamic eager fetching in Spring Data JPA.