OSIV(Open Session In View)

과녁스·2024년 11월 6일
0

Spring

목록 보기
14/14

OSIV는 웹 요청의 시작부터 뷰가 렌더링될 때까지 영속성 컨텍스트(Hibernate Session 또는 JPA EntityManager)를 열어두는 패턴입니다.

주요 포인트

  1. 트랜잭션이 완료된 후에도 뷰 계층에서 지연 로딩이 작동할 수 있게 합니다.
  2. Spring Boot에서는 기본적으로 활성화되어 있습니다 (spring.jpa.open-in-view=true).
  3. 데이터베이스 연결을 더 오래 유지하므로 성능 문제를 일으킬 수 있습니다.
  4. 비활성화하면 트랜잭션 내에서 지연 로딩을 처리해야 합니다.
  5. 영속성 컨텍스트를 열고 닫는 필터나 인터셉터를 사용하여 구현됩니다.

장/단점

장점

  • 개발자에게 편리하며, 뷰에서 지연 로딩을 허용합니다
  • LazyInitializationException을 줄일 수 있습니다

단점

  • 장시간 실행되는 요청에서 성능 문제를 일으킬 수 있습니다
  • 뷰 렌더링 중 예상치 못한 쿼리가 실행될 수 있습니다

모범사례

  • 고성능 애플리케이션에서는 비활성화
  • 활성화되었을 때의 영향을 인지
  • 대안으로 DTO나 페치 조인 사용을 고려

사용

Spring Boot에서는 기본적으로 OSIV가 활성화되어 있습니다. application.properties 또는 application.yml 파일에서 다음과 같이 설정할 수 있습니다:

spring:
  jpa:
    open-in-view: true

컨트롤러에서 지연 로딩 사용:

@GetMapping("/teams/{id}")
public String getTeam(@PathVariable Long id, Model model) {
    Team team = teamRepository.findById(id).orElseThrow();
    
    // 컨트롤러에서 지연 로딩 사용
    int memberCount = team.getMembers().size(); 
    
    model.addAttribute("team", team);
    model.addAttribute("memberCount", memberCount);
    return "team-detail";
}

예시에서 team.getMembers()는 지연 로딩을 사용합니다. OSIV가 활성화되어 있기 때문에 트랜잭션이 끝난 후에도 컨트롤러에서 지연 로딩이 가능합니다.

REST API에서 OSIV 사용:

@GetMapping("/api/teams/{id}")
public TeamDTO getTeamApi(@PathVariable Long id) {
    Team team = teamRepository.findById(id).orElseThrow();
    
    // DTO 변환 중 지연 로딩 사용
    return new TeamDTO(team.getName(), team.getMembers().size());
}

API 응답을 생성하는 동안에도 지연 로딩을 사용할 수 있습니다.

OSIV를 사용하면 트랜잭션 범위를 벗어난 곳에서도 지연 로딩을 편리하게 사용할 수 있습니다. 하지만 데이터베이스 커넥션을 오래 물고 있기 때문에, 성능에 주의를 기울여야 합니다

profile
ㅎㅅㅎ
post-custom-banner

0개의 댓글