[spring(스프링)] JPA에서의 즉시 로딩과 지연 로딩 _디버깅의 눈물
즉시 로딩(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란 데이터베이스의 테이블과 매핑되는 자바 객체를 말합니다.