지연 로딩

Violet_Evgadn·2023년 4월 24일
0

DB연동

목록 보기
20/22
post-custom-banner

지연 로딩

지연 로딩이란?

JPA 측에서 Entity가 실제로 사용되기 전까지 DB 조회를 지연하는 것을 말한다.

문제는 지연 로딩을 사용하기 위해서는 DB 조회를 하지는 않았지만 필요한 순간 바로 조회하여 저장할 "가짜 객체"가 필요하다는 점인데, 이 객체를 프록시 객체라고 한다.

프록시 객체는 처음 사용할 때 1번만 초기화되고, 프록시 객체를 통해서도 실제 Entity에 접근할 수 있다.

영속성 컨텍스트에 만약 찾는 Entity가 존재할 경우 em.getRefrence()를 통해 프록시 객체를 활용하더라도 실제 Entity가 저장된다는 특징이 있다.

// 엔티티 직접 조회 - 영속성 컨텍스트에 없으면 DB 조회
Member member = em.find(Member.class, 100L);

// 엔티티를 실제 사용하는 시점까지 미루는 프록시 객체
Member member = em.getReference(Member.class, 100L);

방법

@ManyToOne이나 @OneToMany 어노테이션에 fetch라는 Parameter가 존재한다.

FetchType.EAGER일 경우 즉시 로딩, FetchType.LAZY일 경우 지연 로딩이 수행된다.

즉시 로딩(EAGER) 같은 경우 Hibernate는 SQL 조인을 통해 한 번에 조회하고, 지연 로딩(LAZY) 같은 경우 Proxy를 실제로 활용할 때 초기화하면서 DB를 조회하여 데이터를 저장한다.

어노테이션로딩 기본 전략

어노테이션로딩 전략
@ManyToOne, @OneToOne즉시 로딩(FetchType.EAGER)
@OneToMany, @ManyToMany지연 로딩(FetchType.LAZY

참고로 모든 연관관계에 지연 로딩을 사용하는 것을 추천하며 개발 완료 단계 때 실제 사용 상황을 보며 최적화하는 방식을 추천한다.

Collection에 FetchType.EAGER를 사용하는 것은 그렇게 권장되지는 않는데, 컬렉션 즉시 로딩은 항상 Outer Join을 활용하기 때문에 필요한 것보다 더 많은 데이터를 가지고 오는 경우가 발생하기 때문이다.

CASCADE

특정 Entity를 영속 상태로 만들 때 연관된 엔티티도 동시에 영속 상태로 만들고 싶을 때 활용한다.

CascadeType.PERSIST로 지정할 수 있으며 @OneToMany 쪽에 명시한다.

이를 활용하면 부모와 자식을 한꺼번에 저장할 수 있게 되며 삭제할 때도 부모와 자식을 동시에 삭제할 수 있다.

참고로 CascadeType.REMOVE는 연결이 끊어질 때 자동 삭제한다기보다는 연관 Entity가 삭제될 때 같이 삭제하라는 영속성 전이와 관련된 옵션이다.

고아 객체

JPA는 부모 Entity와 연관관계가 끊어진 자식 Entity를 자동으로 삭제하는 기능을 가진다.

부모 Entity에서 자식 Entity를 삭제만 한다면 부모와 자식 간 참조가 끊어지는 것으로 이해하여 DB 레벨에서도 삭제된다.

DB의 Remove가 CASCADE로 설정되었다고 생각하면 편하다.

@OneToOne에서도 연결이 끊어지면 자동으로 DB에서 삭제한다.

연결이 끊어진 엔티티를 같이 삭제하라는 의미로 Owner 객체와 참조가 끊어진 객체들을 자동으로 삭제시켜야 하는 경우 유용하다.

profile
혹시 틀린 내용이 있다면 언제든 말씀해주세요!
post-custom-banner

0개의 댓글