지난 번에는 Fetch전략인 LAZY와 EAGER에 대해 알아봤다. 하지만 조회된 테이블의 연관관계 된 테이블까지 써야한다면 @EntityGraph를 사용하는게 좋다. 이 글에서는 @EntityGraph에 대해서 다뤄볼 예정입니다. 

n+1이 뭔지 Fetch전략에 대해서 잘 모르신다면 아래 링크를 먼저 읽어보는 것도 좋을 것 같습니다.

2022.08.03 - [데이터베이스/JPA] - [JPA] Fetch 전략과 @EntityGraph로 n+1 해결하기(1)

 

[JPA] Fetch 전략과 @EntityGraph로 1+n 해결하기(1)

JPA를 사용하기전 Mybatis를 사용할 때는 xml로 객체를 SQL에 매핑하는데 시간을 썼지만 JPA는 자동으로 쿼리를 만들어줘서 편하게 사용하고 있었다. 하지만 편한 만큼이나 나도 모르게 1 + n 쿼리가

whitewise95.tistory.com


@EntityGraph란?

엔티티 및 연관된 엔티티를 로드할 때 성능이 향상되고 JOIN 전략을 사용하여 그래프의 정의된 방식으로만 데이터를 검색하기 때문에 데이터베이스의 모든 정보를 한 번에 조회할 수 있습니다.

왼쪽은 그냥 조회를 할 경우 조회문이 2번 발생했습니다.오른쪽은 EntityGraph를 사용했을 때   join을 사용하여 쿼리문이 하나만 발생되었습니다.  아래의 예시는 연관관계가 하나밖에 없을 경우지만 연관관계가 많다면 더욱 EntityGraph의 중요성을 깨닫게됩니다.

왼쪽은 그냥 조회를 할경우 오른쪽은 EntityGraph를 사용했을 때 사용된 쿼리 입니다.

 

 


@EntityGraph 예제

아래 Car 클래스는 master와 n : 1 연관관계가 맺여진 상태입니다.

@Entity
public class Car {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    private Master master;

    public Car() {}
}

 

 

첫번째

첫번째 방법은 매우 간단합니다. @EntityGraph 어노테이션을 사용하고 attributePaths 속성에 join하고 싶은 변수명을 써주면 됩니다. 예를 들면 위 Car라는 클래스 안에 Maste 클래스는 연관관계가 되어있고 변수명이 master 입니다. 즉 ,  attributePaths = "master" 라고 해주시면됩니다. 

public interface CarRepository extends JpaRepository<Car, Long> {

    @Override
    @EntityGraph(attributePaths = "master")
    Optional<Car> findById(Long aLong);
}

 

 

 

두번째 

두번째 방법으론 @NamedEntityGraph를 이용하여 Entity클래스에서 정의해주는 방법인데요 @NamedEntityGraph 속성에 name에는 repository에서 사용할 이름을 정의해주고  attributeNodes속성은 join을 해줄 연관관계가된 클래스의 변수명을 적어주면 됩니다.

@Entity
@NamedEntityGraph(name = "car.fetchMaster", attributeNodes = @NamedAttributeNode("master"))
public class Car {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    private Master master;

 }

 

그리고 repository에서 @EntityGraph 에는 다른 속성없이 @NamedEntityGraph에 정의해준 이름을 적어주면 됩니다.

public interface CarRepository extends JpaRepository<Car, Long> {

    @Override
    @EntityGraph("car.fetchMaster")
    Optional<Car> findById(Long aLong);
}

 

 


참고하며 좋은 자료 및 참고했던 자료

 

스프링 데이터 JPA - Fetch Join과 @EntityGraph

모든 소스 코드는 여기에서 확인 가능합니다. Fetch Join 과 @GraphEntity 를 소개하기 전에 JPA를 사용하다보면 겪을 수 있는 사례 하나를 소개합니다. Member Entity 와 Team Entity 가 다대일 관계( @ManyToOne..

jaime-note.tistory.com

 

복사했습니다!