spring(스프링)

[spring(스프링)] JPA에서의 즉시 로딩과 지연 로딩 _디버깅의 눈물

디버깅의 눈물 2023. 4. 13. 12:37

 

즉시 로딩(Eager Loading)

 

즉시 로딩은 엔티티를 로딩 할 때, 해당 엔티티와 관계가 있는 다른 엔티티들도 함께 로딩되는 방식입니다.

 

 

@Entity
public class Order {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    private String customerName;
 
    @OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
    private List<OrderItem> orderItems = new ArrayList<>();
 
    // getters, setters, constructors...
}

 

 

예를 들어, Order 엔티티와 관계가 있는 OrderItem 엔티티를 즉시 로딩으로 설정하면, Order 엔티티를 로딩 할 때 해당 Order와 관계가 있는 모든 OrderItem 엔티티도 함께 로딩 됩니다.

 

즉시 로딩은 데이터베이스에서 필요한 모든 데이터를 한번에 로딩 하기 때문에 성능이 좋지만, 데이터의 양이 많은 경우 부하가 증가할 있습니다.

 

 

지연 로딩(Lazy Loading)

 

지연 로딩은 해당 엔티티가 실제로 사용될 로딩되는 방식입니다. 연관된 데이터를 프록시 객체를 이용해 조회합니다. 객체 간 연관관계가 설정된 경우, 해당 객체의 프록시 객체를 생성하고, 이 프록시 객체를 통해 실제 객체를 로드 하지 않고, 연관된 객체에 대한 접근이 필요한 시점에서 실제 객체를 로드 합니다.

 

 

@Entity
public class Order {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    private String customerName;
 
    @OneToMany(mappedBy = "order", fetch = FetchType.LAZY)
    private List<OrderItem> orderItems = new ArrayList<>();
 
    // getters, setters, constructors...
}

 

 

예를 들어, Order 엔티티와 관계가 있는 OrderItem 엔티티를 지연 로딩으로 설정하면, Order 엔티티를 로딩 할 때는 OrderItem 엔티티가 로딩되지 않고, OrderItem 엔티티가 실제로 사용될 때(예 : Order 엔티티에서 OrderItem의 목록을 조회할 때) 해당 OrderItem 엔티티가 로딩됩니다.

 

지연 로딩은 필요한 데이터만 로딩하기 때문에 성능이 좋지만, 데이터의 양이 많아도 필요한 데이터만 로딩 하므로 부하를 줄일 있습니다.

 

 

 

즉시 로딩과 지연 로딩 중 어떤 것을 사용해야 할까?

 

JPA에서 지연 로딩과 즉시 로딩 중에서 어떤 것을 사용해야 하는지는 상황에 따라 다릅니다. 따라서 일반적으로 어떤 것이 더 나은 것인지를 권장하는 것은 어렵습니다. 하지만 몇 가지 고려해야 할 사항이 있습니다.

 

먼저, 지연 로딩은 필요한 시점에만 데이터를 로딩하기 때문에 성능 측면에서 이점이 있습니다. 하지만 지연 로딩을 사용하면 프록시 객체를 사용하기 때문에 객체 그래프를 탐색하는 과정에서 예기치 않은 예외가 발생할 수 있습니다. 또한, 지연 로딩을 사용하면 N+1 문제가 발생할 수 있습니다.

 

반면에, 즉시 로딩은 연관된 객체를 즉시 로딩하기 때문에 객체 그래프를 탐색하는 과정에서 예기치 않은 예외가 발생하지 않습니다. 그러나 즉시 로딩은 필요하지 않은 데이터까지 로딩하기 때문에 메모리를 더 사용하고 성능도 떨어질 수 있습니다.

 

따라서 JPA에서는 지연 로딩을 기본으로 사용하고, 필요한 경우 즉시 로딩을 사용하는 것이 좋습니다. 또한, 즉시 로딩을 사용할 때는 FETCH JOIN과 같은 방법을 사용하여 성능을 최적화할 수 있습니다.

 

하지만 가장 중요한 것은 상황에 따라 적절한 방법을 선택하는 것입니다. 어떤 경우에는 지연 로딩이 적합하고, 어떤 경우에는 즉시 로딩이 적합할 수 있습니다. 따라서 개발자는 상황을 파악하고 적절한 방법을 선택해야 합니다.

 

 

 

 

*JPA에서 Entity 데이터베이스의 테이블과 매핑되는 자바 객체를 말합니다.