OSIV란
OSIV(Open Session In View)는 '세션을 뷰에서 연다'는 직역에서 유추할 수 있듯이 DB 세션의 생명주기를 뷰 레이어에서 관리하는 전략을 말한다. 웹 어플리케이션에서 Hibernate와 같은 ORM을 사용할 때 이 전략이 대개 동반되는데, ORM이 OOP와 RDB의 패러다임 불일치를 해결하는 과정에서 Lazy Loading 옵션을 지원하기 때문이다.
패러다임 불일치란
여기서 말하는 패러다임 불일치란 다음 세 가지 대표적인 예시에서 세 번 째 예시를 말한다.
- [객체의 동일성 관리 안됨] ID가 같은 객체면 DB에서는 동일한 객체이지만, Java 앱에서 Select를 따로 따로 한 다음에 Java 객체에 담아 equals 비교를 하면 별도의 @equals 오버라이딩 없이는 해시코드가 달라 다른 것으로 취급하는 것
- [객체 속성 관리 안됨] 특정 컬럼만 Select해서 DTO에 담으면 조회하지 않은 컬럼은 null로 비어있는 것
- [객체 간 연관관계 관리 안됨] 1:N 관계가 있는 객체 A,B가 Java 메모리에서 객체로 존재할 때는 접근 연산자(”.”)로 탐색이 가능하지만, DB에서 조회하고 나면 그 관계는 개발자가 의도적으로 맺어주지 않는 이상 더 이상 관리되지 않는다.
OOP는 현실 세계를 잘 표현하기 위한 것이다. 현실에서 책을 펼쳐보면 당연히 작가가 누군지 알 수 있어야 한다. 하지만 책이라는 데이터가 RDB만 갔다 나오면 작가 정보가 없어져 있을 수도 있다. 개발자가 join해서 같이 가져오지 않는 이상 말이다.
Fetch 전략의 등장
ORM은 이러한 패러다임 불일치를 해결하기 위해 연관 관계에 있는 데이터들을 알아서 로드해주는 기능을 지원한다. 그런데 이제 관련 있는 모든 데이터를 Eagerly 로드할 것이냐, Lazily 로드할 것이냐의 선택을 해야하고, 당연히 모든 케이스에 대해서 모든 연관 데이터를 Eagerly 로드하는 것은 메모리 측면에서나 성능 측면에서 효율적이라고 볼 수 없기 때문에 Lazy Loading이 디폴트인 것이다.
Lazy Loading과 open-in-view의 관계
Lazy Loading이 필요한 것과 OSIV 전략은 어떤 관계가 있을까? OSIV가 활성화 되어 있어야 Lazy Loading이 가능하다. 서비스 레이어*에서 미처 다 로드되지 못한 데이터가 뷰 레이어**에서는 필요하게 되었을 수 있기 때문이다.
* 서비스 레이어란
여기서는 비즈니스 로직을 수행하는 레이어로, 뷰 레이어와 DB 사이를 총칭하였다.
** 뷰 레이어란
기본적으로 모델 데이터를 가공하여 뷰에 전달하는 컨트롤러와, 서버 사이드 렌더링인 경우에는 HTML 파일을 생성하고 반환하는 Tymeleaf나 JSP 등의 템플릿 엔진을, JSON을 반환하는 경우에는 JSON을 직렬화 하여 response를 생성하는 부분을 뷰 레이어라고 한다.
그 때 트랜잭션을 통해 데이터를 추가로 로드하려고 하는데 OSIV가 활성화 되어있지 않다면 `LazyInitializationException`이 발생할 것이다. DB 세션을 서비스 레이어가 관리하게 되면 서비스 레이어가 필요하다고 생각하는 트랜잭션을 다 완수한 후에 DB 세션을 닫아버리고 뷰 레이어는 권한이 없기 때문이다.
이러한 이유로 DB 세션을 서비스 레이어가 관리하는 것이 아니라 뷰 레이어가 하겠다는 것이 바로 OSIV이다. 즉, 뷰 레이어가 DB 세션을 열었다가, 뷰를 렌더링할 때 뒤 늦게 없는 데이터도 가져오고(= LazyLoading하고) 뷰 생성까지 끝나면 DB 세션을 닫겠다는 것이다.
'웹' 카테고리의 다른 글
ORM 사용 이유와 장점 (1) | 2024.12.13 |
---|---|
AWS Code Deploy 사용법 (0) | 2024.11.30 |
OSIV와 SSE (0) | 2024.10.29 |
OSIV는 안티패턴? (2) | 2024.10.28 |
JAVA 앱 배포하기 (0) | 2020.07.28 |