Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Spring] OSIV란? #62

Open
leejohy-0223 opened this issue Nov 1, 2022 · 1 comment
Open

[Spring] OSIV란? #62

leejohy-0223 opened this issue Nov 1, 2022 · 1 comment
Labels
SPRING 스프링 질문

Comments

@leejohy-0223
Copy link
Collaborator

leejohy-0223 commented Nov 1, 2022

1. OSIV에 대해서 설명해주세요.

키워드

Session, EntityManager, View, ThreadLocal, Interceptor

@leejohy-0223 leejohy-0223 added the SPRING 스프링 질문 label Nov 1, 2022
@leejohy-0223
Copy link
Collaborator Author

leejohy-0223 commented Nov 2, 2022

1. OSIV란?

  • 원래는 세션(영속성 컨텍스트)과 트랜잭션 범위가 같지만, 스프링이 제공하는 OSIV를 통해 트랜잭션은 서비스 계층까지(@transactional), 영속성 컨텍스트는 뷰까지 열어둘 수 있습니다. 즉 영속성 컨텍스트를 뷰까지 열어, 지연 로딩이 가능하도록 함으로써 뷰에서 렌더링이 가능하도록 합니다.
  • JPA에서는 OEIV(Open EntityManager in View)라고 합니다.
    • hibernate == Session, JPA == EntityManager

2. 왜 활성화하는지?

기본적으로 스프링 컨테이너는 트랜잭션, 영속성 컨텍스트를 동일하게 가져가는 전략을 세웁니다. 문제는 프레젠테이션 계층에서 이미 준영속 상태(영속성 컨텍스트가 사라져서)인 엔티티를 지연 로딩 할 때 발생합니다. 지연 로딩 시 프록시 객체를 대상으로 호출되므로 이를 통해 영속성 컨텍스트에 실제 엔티티 생성을 요청하고 DB를 조회해서 객체를 생성하고 조회할 수 있는 과정이 거쳐져야 하는데, 이미 영속성 컨텍스트가 닫혀있으므로 LazyInitializationException이 발생하게 됩니다. 이를 해결하기 위해 프레젠테이션 계층에서도 지연로딩이 가능하도록 도와주는게 OSIV입니다.

3. 동작원리

image

osiv=on 하게되면 위와 같이 OpenEntityManagerInViewInterceptor가 인터셉터로 등록되고 핸들러 호출전에 실행됩니다. 이 안에서는 EntityManagerFactory를 통해 세션(EntityManager)을 생성하고 쓰레드 로컬에 할당합니다. 즉 트랜잭션 단계에서 할당되어야 할 세션을 로직 호출 전에 미리 할당하게 됩니다.
(모든 요청에 EntityManager를 생성하긴 하지만, 커넥션은 @transaction 요청에 대해서만 형성합니다.)

4. 최적화

  • OSIV를 끄고, 엔티티는 트랜잭션 내에서만 사용하며 나머지 계층에서는 DTO를 활용합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SPRING 스프링 질문
Projects
None yet
Development

No branches or pull requests

1 participant