최종 프로젝트를 진행하던 도중, @EntityGraph
에 대해 조사를 하게 되었다.
특정 상황에 따라 Entity에 선언된 fetch 전략이 아닌, 다른 전략을 사용할 때가 있기 때문이다.
그 이유에 대해서 알아보는 시간을 가져보겠다.
LAZY
와 EAGER
가 존재한다.join
을 통해서 조회한다.join
을 사용하는 것은 아닌 것 같다. (N+1 문제)@EntityGraph
를 사용할 수 있다.public interface BoardRepository extends JpaRepository<Board, Long> {
@EntityGraph(attributePaths = {"comments"})
Optional<Board> findWithCommentById(Long id);
}
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// 글로벌 fetch 전략은 LAZY이다.
@OneToMany(mappedBy = "board", fetch = FetchType.LAZY)
private List<Comment> comments = new ArrayList<>();
}
@Entity
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "board_id")
private Board board;
}
public interface BoardRepository extends JpaRepository<Board, Long> {
// 하지만, 해당 메소드를 통해 엔티티를 조회한다면, EAGER 형식으로 가져온다.
@EntityGraph(attributePaths = {"comments"})
Optional<Board> findWithCommentById(Long id);
}
// comments를 LAZY 형태로 가져올 때
Board board = boardRepository.findById(2L);
// comments를 EAGER 형태로 가져올 때
Board board = boardRepository.findWithCommentById(2L);
@OneToMany
를 EAGER
로 가져오게 되면 MultipleBagFetchException
예외가 발생한다.@EntityGraph
가 적용된 메소드를 작명할 때, Spring Data에서 제공하는 쿼리 메소드 문법에 맞지 않도록 해야한다.