티스토리 뷰

반응형

준영속 상태의 지연 로딩 문제를 해결

영속성 컨텍스트 전략을 기본으로 사용하는 스프링에서는 트렌잭션이 Service 계층에서 시작하여 끝나는 시점에서 영속성 컨텍스트 또한 함께 종료된다.

준영속 상태에서는 변경감지지연로딩이 되지 않는다.

준영속 상태의 지연로딩

View 계층에서 엔티티를 사용할 경우 관련된 엔티티도 함께 사용해야 하는데 만일 초기화 되지 않은 프록시를 준영속 상태에서 호출할 경우 문제가 발생한다.

이러한 문제를 해결 하기 위해 JPA는 두 가지 방식을 제안하고 있다.

  • 뷰가 필요한 엔티티를 미리 로딩해 두는 방법
  • OSIV를 사용하여 엔티티를 항상 영속 상태로 유지하는 방법

뷰가 필요한 엔티티를 미리 로딩해 두는 방법

  • 글로벌 페치 전력 수정
  • JPQL 페치 조인
  • 강제 초기화

A. 글로벌 페치 전략 수정

모든 호출 방식을 Eager 전략으로 바꾸는 방식으로 문제를 해결할 수 있는 대안 이지만 두가지 문제가 있다.

  • 사용하지 않는 엔티티 호출
  • N+1 문제

B. JPQL 페치 조인

JPQL을 호출하는 시점에 함께 로딩할 엔티티를 선택할 수 있는 방법에서으로 N+1 문제를 와 지연로딩 상태를 함께 해결하는 방식에서는
좋은 대안이지만 리포지토리 메소드 증가 ,데이터 접근 계층 침범 의 문제가 발생한다.

C. 강제 초기화

class OrderService {
    @Transactional
    public Order findOrder(id) {
        Order order = orderRepository.findOrder(id);
        order.getMember().getName();
        return order;
    }
}

가장 쉽게 사용할 수 있는 방법이지만 프록시를 초기화하는 역할을 서비스 계층이 담당하면
뷰가 필요한 엔티티에 따라 서비스 계층의 로직을 변경해야 할 것이다.

즉, 프레젠테이션 계층이 서비스 계층의 역할에 침범하는 문제가 발생하게 된다.

OSIV(Open Session In View)

영속성 컨텍스트를 항상 열어둔다는 뜻으로 서비스 계층을 넘어 뷰 계층까지도 지연 로딩을 사용할 수 있다.

문제는 모든 영역에서 데이터 변경(변경 감지)가 가능하다는 것이다.

A. 엔티티를 읽기 전용 인터페이스로 제공

엔티티를 직접 노출하는 대신에 읽기 전용 메소드만 제공하는 
인터페이스를 프레젠테이션 계층에 제공하는 방법이다.

B. 엔티티 레핑

읽기 전용 메소드만 가지고 있는 엔티티를 감싼 객체를 
만드록 이것을 프레젠테이션 계층에 반환하는 벙법
class MemberWrapper{
    private Member member;
    public MemberWrapper(member){
        this.member=member;
    }

    public String getName(){
        member.getName();
    }
}

C. DTO 반환

가장 전통적인 방법으로 엔티티 대신에 데이터만을 전달하는 DTO를 생성해서 반환하는 방법이다.
OSIV를 사용하는 장점을 살릴 수 없고 동일 엔티티를 하나 더 만들어야 하는 번거로움이 발생한다.
반응형

'JPA' 카테고리의 다른 글

Spring Data 페이징  (0) 2022.06.27
ORM에서의 객체 연관 매핑  (0) 2022.06.26
JPA - 상속 관계 매핑  (0) 2022.06.24
프록시  (0) 2022.05.14
임베디드 타입, 엔티티 타입  (0) 2022.05.13
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함