FetchType.LAZY

 

실무에서 일반적으로 FetchType은 LAZY로 설정을 해둔다고 합니다.

그 이유가 궁금해서 본 프로젝트에서 일부러 default가 LAZY로 되어있는 엔티티의 필드값을

FetchType.EAGER로 바꿔보기로 했습니다.

 

 

우선 EAGER로 fectchType을 설정한 뒤 실행해보겠습니다.

 

Before(EAGER)

@OneToMany 같은 경우.

어노테이션을 클릭해보면 default가 LAZY로 되어있는 것을 확인할 수 있습니다.

 

하지만 @ManyToOne이나 @OneToOne같은 경우는 eager가 default로 되어있기에 유의해야 합니다.

 

다시 본론으로 돌아와서 EAGER 상태에서 상품관리 화면을 열어보겠습니다.

상품관리화면 같은 경우 item에 대한 정보만 필요한 것을 알 수 있습니다.

그런데 쿼리문을 확인해보면

(좌)상품의 숫자, 상품 정보(우)

 

상품 주문서 정보

 

보면 상품 주문서(orderitem) 정보는 필요도 없는데 조회하는 걸 확인 할 수 있습니다.

원인을 찾아보겠습니다.

 

@Table(name = "item")
@Getter
@Setter
@ToString
public class Item extends BaseEntity {

    @Id
    @Column(name="item_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;       //상품 코드

    @Column(nullable = false, length = 50)
    private String itemNm; //상품명

    @Column(name="price", nullable = false)
    private int price; //가격

    @Column(nullable = false)
    private int stockNumber; //재고수량


    @Column(nullable = false)
    private String itemDetail; //상품 상세 설명

    @Enumerated(EnumType.STRING)
    private ItemSellStatus itemSellStatus; //상품 판매 상태

	//원인
    @OneToMany(mappedBy = "item", cascade = CascadeType.DETACH, orphanRemoval = true, fetch = FetchType.EAGER)
    private List<OrderItem> orderItems;

    @OneToMany(mappedBy = "item",cascade = CascadeType.REMOVE)
    private List<CartItem> cartItems;

    @OneToMany(mappedBy = "item", cascade = CascadeType.REMOVE, orphanRemoval = true)
    private List<ItemImg> itemImgs = new ArrayList<>();

    @Column(name = "discount")
    private int discount;

item 정보를 가져오기위해 item Entity를 조회하는 과정에서  orderItems 필드 연관관계에 있고

즉시 로딩(FetchType.EAGER)를 실행하면서  orderItems에 있는 정보들을 가져오게 되는겁니다.

 

반면 cartItems 같은 경우엔 똑같이 연관관계에 있지만 fetchType이 default인 LAZY 상태로 설정되어있기에

cartItems에 있는 정보들은 조회하지 않고

cartItems에 있는 정보에 액세스할때만 해당 entity를 조회하게 설정해놓기 위해 LAZY 설정을 해놓는 것입니다.

 

 

 

 

After(LAZY)

이번에 FetchType을 LAZY(Default)로 설정해놓고 실행해보겠습니다.

 

 

 

 

이번엔 깔끔하게 아이템만 조회하는 것을 확인 할 수 있습니다.

 

그래서 항상 기본적으로 fetchType을 LAZY로 설정을 해놓는 것입니다.

 

 

하지만 LAZY로 설정하는 것의 단점 또한 존재합니다.

 

1. 지연 초기화 예외입니다. 지연 가져오기 유형을 사용할 때 개발자가 직면하는 가장 일반적인 문제는

LazyInitializationExcepion입니다. 이 예외는 Hibernate 세션이 닫힌 후 개체를 느리게 가져오고 해당 데이터에 액세스 할 때 발생합니다.

 

2. N + 1 문제가 발생합니다. 이 문제는 컬렉션의 요소에 하나씩 액세스 할 때 발생하며 결과적으로 1(초기로드의 경우) + N(컬렉션의 각 항목에 대해) 데이터 베이스에 대한 쿼리가 발생하여 성능에 상당한 영향을 미칠 수 있습니다.

 

 

'Deep Dive' 카테고리의 다른 글

iam 계정으로 ec2 접속하기  (0) 2023.07.09
셔플링 알고리즘  (0) 2023.07.02
타이머 기능  (0) 2023.07.02
JPA Repository & QueryDSL  (0) 2023.06.23
CS 공부 순서  (0) 2023.06.05

+ Recent posts