JPA could not initialize proxy - no Session 원인 / 해결방법
could not initialize proxy - no Session
해당 오류는 JPA 의 open-in-view 설정과 관련이 있습니다.
OSIV
open-in-view는 OSIV(Open Session In View) 라 하며 영속성 컨텍스트의 범위를 설정하는 옵션입니다.
JPA default 설정 값은 true 이고 영속성 컨텍스트가 트랜젝션의 범위를 넘어서 요청이 끝날 때까지 살아있게 됩니다.
false 설정의 경우 트랜젝션 범위 내에서만 영속성 컨텍스트가 살아있게 됩니다.
원인
open-in-view 설정이 false 인 상태에서 트랜젝션 없이 연관관계가 FetchType.LAZY 로 설정한 객체에 접근할 때 발생.
/*application.yml*/
spring:
jpa:
open-in-view: false
FetchType.LAZY로 설정할 경우 연관관계로 설정한 객체에 접근하기 전에는
연관관계로 설정한 객체는 프록시 객체가 됩니다.
트렌젝션의 범위를 벗어난 곳에서 이 프록시 객체에 접근했기 때문에 (영속성 컨텍스트가 살아있지 않기때문에) 프록시를 초기화 할 수 없다는 오류를 발생시키는 것 입니다.
해결방법
연관관계로 설정한 객체에 접근 하는 코드가 있는 메서드에 @Transactional 을 추가해서 트렌젝션의 범위내로 처리함으로써, 프록시 객체에 접근 할 수 있게 설정합니다.
open-in-view : ture 설정의 단점
메모리 누수와 성능 문제
OSIV는 데이터베이스 세션을 요청과 응답 사이에 열어두기 때문에, 해당 세션이 길게 열려있는 동안 메모리 누수가 발생할 수 있습니다. 또한, 연결된 세션의 수가 많아지면 데이터베이스 커넥션 풀의 리소스를 과도하게 사용할 수 있어 성능에 영향을 미칠 수 있습니다.
커넥션 리소스 관리 문제
OSIV로 인해 커넥션은 웹 요청 동안 계속해서 유지되므로, 동시에 많은 요청이 들어올 경우 커넥션 리소스가 고갈될 수 있습니다.
트랜잭션 관리 복잡성
OSIV를 사용하면 트랜잭션의 범위가 확장되어 웹 요청 동안 영속성 컨텍스트와 트랜잭션이 열려있게 됩니다. 이로 인해 트랜잭션 관리가 복잡해질 수 있으며, 롤백 등의 예외 처리도 어려워질 수 있습니다.
데이터 정합성 문제
OSIV로 인해 데이터 변경이 뷰 렌더링 단계까지 지연될 수 있습니다. 이로 인해 데이터베이스와 뷰 간의 일관성이 유지되지 않을 수 있습니다.
서버 부하 증가
OSIV는 데이터베이스 세션을 요청 동안 계속 열어두기 때문에, 서버 리소스 사용량이 증가할 수 있습니다. 특히, 많은 동시 요청이 발생하는 경우 부하가 증가할 수 있습니다.
open-in-view : ture 설정의 장점
어디서든 영속성 컨텍스트 프록시에 접근 할 수 있습니다. 끝.