문제상황
- SpringBoot 실행시 Console창에 아래와같은 Warn 경고가 뜨게된다.
WARN 5800 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
- open-in-view 가 기본적으로 활성화되어있고 비활성화를 하려면
spring.jpa.open-in-view
를 명시적으로 구성하라고한다. 그렇다면 open-in-view는 무엇일까?
Open-Session-In-View (OSIV)
- JPA가 말하는 open-in-view는 Open-Session-In-View(OSIV)를 뜻한다.
OSIV ON

- 기본적으로 OSIV는
spring.jpa.open-in-view=true
가 기본값으로 기본적으로 활성화가 되어있다.
- OSIV 전략은 트랜잭션 시작처럼 최초 데이터베이스 커넥션 시작 시점부터 API 응답이 끝날때 까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지한다. 그러므로 ViewTemplate 이나 API 컨트롤러에서 지연로딩이 가능했던 것이다.
지연로딩은 영속성 컨텍스트가 유지되어있어야 가능하고, 영속성 컨텍스트는 기본적으로 데이터베이스 커넥션을 유지한다.
그런데 이 전략은 너무 오랜시간 동안 데이터베이스 커넥션 자원을 사용하기 때문에, 실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 모자랄 수 있다.
OSIV OFF

spring.jpa.open-in-view=false
를 하게되면 OSIV는 비활성화가 된다.
- OSIV를 끄면 트랜잭션을 종료할때 영속성 컨텍스트를 닫고, 데이터베이스 커넥션도 반환한다. 따라서 커넥션 자원을 낭비하지 않는다.
OSIV를 끄면 모든 지연로딩은 트랜잭션 안에서 처리를 해야한다.
문제해결 및 나의 생각
- 나의 생각은 OSIV를 비활성화 해두는게 맞다고 본다. 나의 경우 소규모 개인 프로젝트만 하고있어서 그럴지도 모르겠지만, Entity를 지연로딩하는 곳은 서비스 계층의 트랜잭션 내에서만 모두 처리하게 되어있다. Controller 계층까지 갈 필요없이 서비스 로직내에서 Entity를 DTO로 가공하는 단계를 거쳐서 DTO를 Controller에 반환하기 때문에 굳이 Controller 계층에서까지 Entitiy를 지연로딩할 필요는 없다고 생각한다.
- Controller 계층은 말그대로 클라이언트의 요청과 응답을 받는 책임,역할을 하는 것 이기때문에 굳이 Entity를 Controller에서 사용할 필요가 있나 싶다. 만약 Entity를 Controller 단계에서 써야할 상황이 생긴다면 사전에 서비스 로직(트랜젹샌 범위) 내에서 DTO로 미리 지연로딩을 시킨후에 Controller에서 사용하는게 맞다고 생각한다.