[Jpa] 준영속과 지연 로딩

준영속 상태와 지연 로딩

  • 엔티티의 생명주기
  • 데이터 접근 전략 등을 설명

준영속 + 트랜잭션범위의 영속성

  • 스프링이나 J2EE 컨테이너는 트랜잭션 범위 영속성 컨텍스트를 기본 전략으로 사용
  • 서비스 계층에서 시작된 트랜잭션 종료시
    • 영속성도 종료
      • 엔티티가 서비스와 레포 계층에서 영속 상태를 유지하지만,
      • 프레젠테이션 (컨트롤러 뷰 등) 에서는 준영속 상태가 됨

지연로딩과 준영속 상태

  • 준영속 상태에서는
    • 엔티티 변경감지
    • 지연 로딩
      • 이 동작하지 않음
  • 코드
    @Entity
    public class Order {
        @Id @GeneratedValue
        private Long id;
    
        @ManyToOne(fetch = FetchType.LAZY) // 지연 로딩 전략
        private Member member; // 주문 회원
    }
    class OrderController {
        public String view(Long orderId) {
            Order order = orderService.findOne(orderId);
            Member member = order.getMember();
            member.getName(); // 지연 로딩 시 예외 발생
        }
    }
  • order 객체는 이미 준영속 상태이며
  • order.getMember 를 통해 지연로딩을 시도해도 값을 가져 오지 못함
    • org.hibernate.LazyInitializationException 이 발생 (하이버네이트가 구현체인 경우)

준영속과 변경 감지

  • 영속성 컨텍스트가 유지되는 서비스 계층(트랜잭션 범위)에서만 작동함
  • 프리젠테이션 계층에서는 영속성 컨텍스트가 종료됨
    • 변경감지가 동작 X
  • 프리젠테이션 계층에서 데이터를 수정하면 안되긴함 ㅋㅋ
  • 비즈니스 로직은 서비스 계층에서 처리
  • 프레젠테이션 계층은 데이터 표시에 집중하자

위 문제들의 해결방안

  • JPQL 의 fetch join 혹은 qdsl fetchJoin 사용
  • OSIV (Open Session In View) 사용
    • 엔티티를 항상 영속 상태로 유지하낟.
    • 성능 문제나 부작용이 있다고 함..


Uploaded by N2T