[TIL] JPA - @EntityGraph

phdljr·2024년 1월 11일
0

TIL

목록 보기
55/70
post-custom-banner

최종 프로젝트를 진행하던 도중, @EntityGraph에 대해 조사를 하게 되었다.
특정 상황에 따라 Entity에 선언된 fetch 전략이 아닌, 다른 전략을 사용할 때가 있기 때문이다.

그 이유에 대해서 알아보는 시간을 가져보겠다.


FetchType

  • 엔티티를 조회할 때, 연관된 엔티티를 어느 시점에 조회할 것인지 정해주는 옵션
  • LAZYEAGER가 존재한다.

FetchType.LAZY

  • 부모 엔티티를 조회할 때, 부모 엔티티만 조회한다.
  • 자식 엔티티가 직접 사용이 됐을 때, 자식 엔티티를 조회하는 쿼리가 발생된다.
  • 엔티티 목록 조회를 할 때, 유리한 전략이다.
    • ex) 게시글 목록 조회

FetchType.EAGER

  • 부모 엔티티를 조회할 때, 자식 엔티티를 같이 한번에 조회한다.
    • JPA는 이를 최적화시키기 위해 웬만하면 join을 통해서 조회한다.
    • 무조건 join을 사용하는 것은 아닌 것 같다. (N+1 문제)
  • 자식 엔티티가 사용이 안돼도, 조회한다.
  • 단일 엔티티 조회를 할 때, 유리한 전략이다.
    • ex) 게시글 조회 시, 댓글도 같이 조회

@EntityGraph - LAZY와 EAGER를 둘 다 쓰고 싶을 때

  • 기본적으로, Entity에 fetch 전략은 하나만 설정이 가능하다.
  • Entity에 설정된 fetch 전략이 아닌, 상황에 따라 다른 fetch 전략을 사용할 수 있도록 도와주는 @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);

주의 사항

  • 두 개 이상의 @OneToManyEAGER로 가져오게 되면 MultipleBagFetchException 예외가 발생한다.
  • @EntityGraph가 적용된 메소드를 작명할 때, Spring Data에서 제공하는 쿼리 메소드 문법에 맞지 않도록 해야한다.
    • 쿼리 메소드처럼 작명되면, 예외가 발생될 것이다.

참조

https://jojoldu.tistory.com/457

profile
난 Java도 좋고, 다른 것들도 좋아
post-custom-banner

0개의 댓글