2024-01-19T15:58:26.533+09:00 WARN 89196 --- [ 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 Session In View라는 옵션이 켜있어서 뜬 경고였다.
Http 요청이 시작될 때 하나의 Hibernate Session(영속성 컨텍스트)를 열고, 요청이 완료될 때까지 Session을 열어두는 패턴이다. 이 패턴을 통해 fetch type이 Lazy Loading인 데이터는 View가 필요한 시점에 로딩이되어 데이터베이스와의 통신을 최적화 할 수 있다. 또한 하나의 요청 동안 열려 있는 세션 덕분에 데이터가 일관성을 유지할 수 있다.

스프링 부트는 기본적으로 Open EntityManger In View를 설정해주어 영속 상태인 객체들은 트랜잭션 안에서는 객체 상태의 변경만 감지하다가 트랜잭션이 종료될 때 DB에 반영된다.
그러나 OSIV가 true일 경우(디폴트가 true이다) Response을 주기 전까지 데이터베이스 커넥션을 가지고 있고 반환이 되면 데이터베이스 커넥션을 돌려주게된다.
이렇게 되면 한 요청이 끝날 때까지 데이터베이스 커넥션을 가지고 있게되어 리소스를 과도하게 사용하여 성능 저하로 이어질 수 있고, 여러 요청이 동시에 같은 데이터를 변경하려하면 데이터 무결성 문제가 일어날 수 있다.
그러면 OSIV 설정을 끄게 되면 트랜잭션이 시작하고 끝날 때까지만 데이터베이스의 커넥션을 유지하기 때문에 커넥션 리소스 낭비를 최소화할 수 있다.
OSIV 설정을 끄게 되면 트랜잭션 안에서 지연로딩을 강제 호출을 해주어야 한다. 그렇지 않으면 다음과 같은 오류가 생기게 된다.
org.hibernate.LazyInitailizationException: failed to lazily initialize a collection of role: ~~
이럴 경우 다양한 해결 방법이 있는데 대표적으로 Fetch Type을 Eager로 바꾸어 즉시 로딩으로 바꾸거나 DTO를 이용하여 강제로 호출하게 하는 방법이 있다.
내가 내린 결론은 역시나 각각의 장단점이 존재하고 상황과 환경에 맞추어 사용해야 한다이다.
OSIV를 켜면 지연로딩을 사용하기에 편하기 때문에 신경을 덜 쓰고 개발을 진행해도 된다는 장점이 있다. 그러나 데이터베이스 커넥션을 오래동안 가지고 있기 때문에 성능 저하를 일으킬 수 있고 데이터 무결성을 해칠 수도 있다.
따라서 실시간 서비스나 동시 요청 수가 많은 어플리케이션에는 부적절하다고 생각이 든다. 만약 개발을 빠르게 진행해야 하고 동시 접속자가 적다면 상관없다고 생각된다.