https://pjstudyblog.tistory.com/75
[Spring Boot] spring.jpa.open-in-view is enabled by default 경고 메시지
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 해당 경고 메시지는
pjstudyblog.tistory.com
위에 포스팅에서는 OSIV패턴에 문제점을 해결하려면 JPA를 열심히 공부해서 해결해야 된다고 했는데 오늘은 그 해결방법에 대해서 포스팅을 작성해보겠습니다.
언제 JPA에서 데이터베이스 커넥션을 가져올까요??
JPA는 데이터베이스 트랜잭션을 시작할 때 데이터베이스 커넥션을 가져오고, 일반적으로 @Transactional 애노테이션을 사용한 서비스 계층의 메소드가 종료되면 데이터베이스 커넥션을 종료해야 합니다. 그러나 서비스 계층 이외에서 JPA의 지연 로딩을 사용하려고 할 경우 데이터베이스 커넥션이 종료되면 문제가 발생할 수 있습니다. 이를 해결하기 위해 OSIV(Open Session in View) 패턴을 사용합니다. spring.jpa.open-in-view 설정이 활성화되면 OSIV 패턴이 적용되어 요청이 반환될 때까지 데이터베이스 커넥션이 유지됩니다. API의 경우 API가 반환될 때까지, View의 경우 화면 렌더링이 완료될 때까지 커넥션이 살아있어 Controller에서 영속성 컨텍스트를 이용한 지연 로딩 전략을 사용할 수 있습니다.
OSIV(Open Session in View) 패턴이란?
다시 말해 OSIV 패턴은 HTTP 요청이 들어올 때 영속성 컨텍스트를 열고, 요청이 끝날 때까지 이를 유지합니다. 이로 인해, 트랜잭션이 종료된 후에는 영속성 컨텍스트 내의 엔티티에 접근만 할 수 있게 설계해야 되며, 지연 로딩을 포함한 다양한 JPA 기능을 사용할 수 있습니다. 추가적으로 OSIV 패턴은 'OpenEntityManagerInViewInterceptor' 또는 'OpenSessionInViewFilter'를 사용하여 구현됩니다.
OSIV가 안티 패턴이지 않을까 라고 생각할 수 있습니다. OSIV가 안티 패턴인지 논쟁한 결과를 링크 공유해드릴게요 .
Hibernate 개발자분도 OSIV 패턴은 안티 패턴이라고 생각하지만 초보자 및 간단한 프로젝트에는 괜찮은 패턴이라고 생각해 기본값으로 spring.jpa.open-in-view 옵션을 활성화 두고 아래에 내용처럼 설정하기로 결정한 것 같습니다.
JPA 사용 x: 경고 없음
JPA 사용: OSIV 설정이 선언되지 않음(OSIV가 켜짐) 경고가 발생
JPA 사용: OSIV=true: 경고 없음(OSIV 설정이 선언)
JPA 사용: OSIV=false: 경고 없음(OSIV 설정이 선언)
https://github.com/spring-projects/spring-boot/issues/7107#issuecomment-271709902
Log a warning on startup when spring.jpa.open-in-view is enabled but user has not explicitly opted in · Issue #7107 · spring-p
Considering OSIV/OEMIV is widely considered an anti-pattern, OpenEntityManagerInViewInterceptor should IMO not be enabled by default. Rather than that it should be opt-in. If this proposal isn't ac...
github.com
그럼 OSIV 패턴을 사용하지 않으면 어떻게 될까??
OSIV 패턴을 사용하지 않으면 트랜잭션이 시작되고 끝날 때까지 데이터베이스 커넥션과 영속성 컨텍스트가 유지되며, 트랜잭션이 끝나면 데이터베이스 커넥션이 끊어지고 영속성 컨텍스트도 더 이상 사용하지 못하기 때문에 Controller 계층에서 지연 로딩 전략을 사용할 수 없습니다. 만약에 사용한다면 LazyInitializationException 예외가 발생하게 됩니다. 따라서 OSIV 패턴을 사용하지 않으면 Controller 계층에서는 영속성 컨텍스트를 사용할 수 없으므로, Service 계층에서 데이터베이스 관련 로직을 마무리해야 합니다.
OSIV 패턴의 장단점 및 주의점
OSIV 패턴은 Controller에서 영속성 컨텍스트를 이용해 지연 로딩 전략을 사용할 수 있는 장점이 있지만, 데이터베이스 커넥션이 오래 유지되는 단점이 있습니다. 커넥션이 오래 유지되면 동시에 많은 요청이 들어올 경우 커넥션 풀이 고갈되어 문제가 발생할 수 있으며, 또한 OSIV 패턴을 사용하면 트랜잭션이 끝난 후에도 엔티티의 변경이 가능해져 의도치 않은 데이터 변경이 발생할 수 있습니다.
결론적으로, OSIV 패턴은 적절히 사용할 경우 유용할 수 있지만, 그에 따른 부작용도 충분히 고려해야 하는 중요한 패턴입니다.
결론
OSIV 패턴은 Controller에서 지연 로딩 전략을 사용할 수 있는 장점이 있지만, 데이터베이스 성능 문제를 일으킬 수 있는 단점이 있습니다. 따라서 규모가 큰 애플리케이션을 개발할 때는 OSIV 패턴을 비활성화하고 Command와 Query를 분리하여 Service 계층에서 데이터베이스 관련 로직을 마무리하는 것이 바람직합니다.
참고자료
[JPA] OSIV (Open-Session-In-View) 동작원리 및 주의사항
예제 및 테스트 코드는 github 에서 확인 가능합니다. OSIV(Open Session In View) 동작원리 및 주의사항 이번엔 JPA/Hibernate 에서 사용되는 개념인 OSIV(Open Session In View) 에 대해 알아보겠습니다. OSIV 는 영속
devoong2.tistory.com
https://f-lab.kr/insight/understanding-osiv-in-spring-boot
스프링 부트에서의 OSIV(Open Session In View) 패턴 이해와 적용
스프링 부트에서 OSIV(Open Session In View) 패턴의 개념, 작동 원리, 적용 방법 및 주의점에 대해 알아봅니다.
f-lab.kr
[Spring] OSIV로 알아보는 Spring Transaction 헤짚기
Spring boot에는 spring.jpa.open-in-view라고 하는 옵션이 있습니다. 이 옵션은 JPA의 OSIV 기능을 ON/OFF 할 수 있는 옵션인데요. 이 옵션이 무엇인지 알아보도록 하겠습니다. OSIV 먼저 이 옵션은 JPA의 OSIV 기
blog.neonkid.xyz
'JAVA > JPA' 카테고리의 다른 글
[QueryDSL] Spring Data JPA + QueryDSL 기본 문법 #2 - from절에 서브쿼리 사용 문제 해결 (0) | 2025.01.30 |
---|---|
[QueryDSL] Spring Data JPA + QueryDSL 설정 #1 (1) | 2025.01.22 |
[JPA] JPA 컬렉션 조회 성능 최적화 #3 - JPA에서 DTO 직접 반환 (3) | 2024.12.14 |
[JPA] JPA 컬렉션 조회 성능 최적화 #2 - @BatchSize (2) | 2024.12.14 |
[JPA] JPA 성능 최적화 #1 - fetch join (0) | 2024.12.10 |