Tech/JPA

@EntityGraph

봄의 개발자 2023. 9. 17.
728x90
반응형

@EntityGraph(attributePaths = {”"})

Spring Data JPA에서 사용하는 어노테이션은로 엔티티 그래프를 정의하는 데 사용된다. 엔티티 그래프는 데이터베이스에서 엔티티와 연관된 다른 엔티티를 로딩할 때 사용되며, 지연 로딩(Lazy Loading)을 효과적으로 방지하고 성능을 최적화하는 데 도움된다.

@EntityGraph 어노테이션은 다양한 속성을 제공하며 그 중에 attributePaths는 로딩할 엔티티의 연관 속성을 지정하는 데 사용된다. 예시를 통해 알아보자.

@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(mappedBy = "customer", fetch = FetchType.LAZY)
    private List<Order> orders;

    // Getter and Setter
}

@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String orderNumber;

    @ManyToOne(fetch = FetchType.LAZY)
    private Customer customer;

    // Getter and Setter
}

이 예제에서 Customer 엔티티와 Order 엔티티는 일대다 관계로 연결되어 있다. @OneToMany와 @ManyToOne 어노테이션을 사용하여 관계를 매핑하고 있다. 이제 @EntityGraph를 사용하여 Customer 엔티티를 조회할 때 연관된 Order엔티티도 함께 로딩할 수 있다.

import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CustomerRepository extends JpaRepository<Customer, Long> {

    @EntityGraph(attributePaths = {"orders"})
    Customer findByName(String name);
}

위의 CustomerRepository 인터페이스에서 findByName 메서드에 @EntityGraph 어노테이션을 사용하고 있는데 이때 attributePaths 속성에 orders를 지정함으로써 Customer 엔티티를 로딩할 때 관련된 Order 엔티티도 함께 로딩하라고 명시하고 있다.

이렇게 하면 Customer 엔티티를 조회할 때 orders 속성에 접근할 때까지 Order 엔티티를 로딩하지 않고 필요할 때 한꺼번에 로딩하게 된다. 이를 통해 지연 로딩 관련 성능 문제를 효과적으로 해결할 수 있다.

추가적 내용: N+1 문제

이 방법은 N+1 문제를 해결하는 방법 중 한가지이다. 우선 N+1 문제는 연관 관계에서 발생하는 이슈로 쉽게 말하면 연관 관계가 설정된 엔티티를 조회할 경우 첫번째 조회 + 해당 개수(N) 만큼 조회되는 현상이다.

처음 조회 쿼리를 통해 정보를 가져온 다음 각 데이터의 연관된 항목들에 접근하려고 할 때마다 개별적인 쿼리가 실행된다. 예를 들어 100명의 고객이 있으면 그들의 주문 목록에 접근하려면 추가적으로 100개의 쿼리가 실행되는 것이다. 이렇게 추가적인 SQL 쿼리가 N개의 엔티티를 가져오기 위해 실행되기 때문에 N+1 문제라고 무른다.

728x90
반응형

댓글