티스토리 뷰

반응형

 준영속 상태의 가장 골치 아픈 문제는 지연로딩 기능이 동작하지 않는다는 점이다.
예를 들어 뷰 랜더링할 때 연관된 엔티티도 함께 사용해야 하는데 연관된 엔티티를 지연 로딩으로 설정해서 프록시 객체로 조회했다고 가정하자.
아직 초기화 하지 않은 프록시 객체를 사용하면 실제 데이터를 불러오려고 초기화를 시도한다.

하지만 준영속 상태는 영속성 컨텍스트가 없으므로 지연 로딩을 할 수 없다. 이때 지연 로딩을 시도하면 문제가 발생한다. 만약 하이버 네이트를 구현체로 사용하면 org.hibernate.LazyInitializationException예외가 발생한다.

준 영속 상태의 지연 로딩 문제를 해결하는 방법은 2가지가 있다.

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

뷰가 필요한 엔티티를 미리로딩해 두는 방법
 - Global fetch 전략 수정
 - JPQL 페치 조인 (fetch join)
 - 강제로 초기화

글로벌 fetch  조인은 관계 설정에서 fetch = EAGER, lazy 로 설정하는 부분이다.

즉시 로딩으로 설정햇을때 단점.

- 사용하지 않는 엔티티를 로딩한다.
- N + 1 문제가 발생한다.
  -> 페치 조인으로 해결 할 수 있다.

강제로 로딩 방법

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

위와 같은 방법으로 order class에 meber에 들어 있는 값을 호출하게되면 강제적으로 로딩을 할 수 있다.

OSIV
open session in view 는 영속성 컨텍스트를 뷰까지 열어둔다는 뜻이다.
영속성 컨텍스트가 살아있으면 엔티티는 영속 상태로 유지된다.
따라서 뷰에서도 지연 로딩을 사용할 수 있다.

요청 당 트랜잭션 방식의 OSIV 문제점
 요청 당 트랜잭션 방식의 OSIV가 가지는 문제점은 컨트롤러나 뷰 같은 프리젠테이션 계층이 엔티티를 변경할 수 있다는 점이다.

위와 같은 방법을 막는 방법.

엔티티를 읽기 전용 인터페이스로 제공
엔티티 레핑
DTO만 반환

---------------------- 2016.08.26 ----------------------
밸류 타입의 @ElementCollection 는 lazy loading일때 답이 없다 -_-;;
강제 로딩을 시켜도 org.hibernate.LazyinitializationException 에러가 발생된다.

식별자가 없는 entity는 이 방법으로 안되는 것 같음.
TypedQuery로도 검색이 안된다.

 

반응형

'Study > JPA' 카테고리의 다른 글

@Version  (0) 2019.04.10
낙관적 락, 비관적 락  (0) 2019.04.10
JPA Entity type, value type 의 특징  (0) 2019.04.10
jpa typedQuery 예제  (0) 2019.04.10
mysql to jpa (java column mapping)  (0) 2019.04.10