스프링이아닌 다른 프레임워크를 사용하는데, OSIV 기능이 꼭 필요하다.
OSIV란? : Open Session In View의 줄임말(JPA에서 엔티티매니저는 하이버네이트에서는 세션이라 부른다.)
직역하면, 세션이 뷰안에서(뷰까지) 존재한다는 것인데..
세션이 뷰까지 살아있으면 좋은점은 Lazy로딩설정된 프록시에 접근해서도 DB에 읽기를 요청할수 있다는 것임.(코드 유지보수 하기에 장점)
(정리 잘된 곳 : https://ykh6242.tistory.com/entry/JPA-OSIVOpen-Session-In-View%EC%99%80-%EC%84%B1%EB%8A%A5-%EC%B5%9C%EC%A0%81%ED%99%94 )
일반적으로
컨트롤러 -> 비지니스 서비스 -> 마이크로 서비스(트랜잭션 시작 및 DB접근후 트랜잭션 종료 = 엔티티매니저 close)
이러한 형태를 취한다면, 마이크로 서비스 단에서만 lazy proxy가 초기화가 가능하다.
그러므로, 비지니스 로직에서는 lazy proxy를 초기화 할 수 없으므로.. 트랜잭션은 마이크로 서비스에서 끝나되, 비지니스 서비스 까지 엔티티매니저를 유지시키고 싶은 것임
시도 V1 : 일단 비지니스 서비스 클래스에 @BusinessService라는 어노테이션이 달려있으면 엔티티매니저가 해당 클래스까지는 유지되도록 해보기.
검색결과 V1 :
<property name="hibernate.enable_lazy_load_no_trans" value="true" />
를 해주면 설정 끝. (정리 잘된 곳 : https://suhwan.dev/2019/10/27/hibernate-detached-entity-proxy-initialization/ )
간단하게 엔티티매니저가 종료될때, 초기화 되지 않은 프록시들은 엔티티매니저팩토리의 레퍼런스를 갖고있는다. 엔티티매니저가 종료된 상태에서도 프록시에 접근하게 되면, 엔티티매니저팩토리 래퍼런스에서 다시 엔티티매니저를 생성하여 DB의 읽기가 가능한 것
(proxy객체를 보면 sessionFactoryUuid 속성에 4c383891-83a4-4a5e-98bf-9d5bde66695c 이런식으로 엔티티매니저팩토리의 값을 가지고 있음)
안티패턴이긴 하다. 왜냐하면 계속 다시 엔티티매니저를 만드는 과정이 있고(커넥션 점유), N+1과 같은 문제가 터질수 있으므로 더 로우레벨 단에서 처리하는게 좋긴 한데...
우리도구에서는 크게 영향이 없다. 단일 프로그램에 커넥션은 오직 1개뿐이며, 레이지로 설정된 프록시는 xToOne일 것이고 xToMany관계는 이미 fetch join으로 가져오므로. 그리고 엔티티매니저 생성과 파괴는 리소스점유가 거의 없다고 함.
(OSIV 자체도 안티패턴이라 한다. https://vladmihalcea.com/the-hibernate-enable_lazy_load_no_trans-anti-pattern/ )
'IT > 트러블슈팅 기록' 카테고리의 다른 글
스프링 프레임워크의 일부기능(IOC와 AOP관련)만 라이브러리처럼 사용하기 (0) | 2022.07.15 |
---|