You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
원래는 세션(영속성 컨텍스트)과 트랜잭션 범위가 같지만, 스프링이 제공하는 OSIV를 통해 트랜잭션은 서비스 계층까지(@transactional), 영속성 컨텍스트는 뷰까지 열어둘 수 있습니다. 즉 영속성 컨텍스트를 뷰까지 열어, 지연 로딩이 가능하도록 함으로써 뷰에서 렌더링이 가능하도록 합니다.
JPA에서는 OEIV(Open EntityManager in View)라고 합니다.
hibernate == Session, JPA == EntityManager
2. 왜 활성화하는지?
기본적으로 스프링 컨테이너는 트랜잭션, 영속성 컨텍스트를 동일하게 가져가는 전략을 세웁니다. 문제는 프레젠테이션 계층에서 이미 준영속 상태(영속성 컨텍스트가 사라져서)인 엔티티를 지연 로딩 할 때 발생합니다. 지연 로딩 시 프록시 객체를 대상으로 호출되므로 이를 통해 영속성 컨텍스트에 실제 엔티티 생성을 요청하고 DB를 조회해서 객체를 생성하고 조회할 수 있는 과정이 거쳐져야 하는데, 이미 영속성 컨텍스트가 닫혀있으므로 LazyInitializationException이 발생하게 됩니다. 이를 해결하기 위해 프레젠테이션 계층에서도 지연로딩이 가능하도록 도와주는게 OSIV입니다.
3. 동작원리
osiv=on 하게되면 위와 같이 OpenEntityManagerInViewInterceptor가 인터셉터로 등록되고 핸들러 호출전에 실행됩니다. 이 안에서는 EntityManagerFactory를 통해 세션(EntityManager)을 생성하고 쓰레드 로컬에 할당합니다. 즉 트랜잭션 단계에서 할당되어야 할 세션을 로직 호출 전에 미리 할당하게 됩니다.
(모든 요청에 EntityManager를 생성하긴 하지만, 커넥션은 @transaction 요청에 대해서만 형성합니다.)
4. 최적화
OSIV를 끄고, 엔티티는 트랜잭션 내에서만 사용하며 나머지 계층에서는 DTO를 활용합니다.
1. OSIV에 대해서 설명해주세요.
키워드
Session
,EntityManager
,View
,ThreadLocal
,Interceptor
The text was updated successfully, but these errors were encountered: