102 lines
9.9 KiB
Markdown
102 lines
9.9 KiB
Markdown
---
|
|
title: OSIV (Open Session In View) anti-pattern — Hibernate User Guide + Vlad Mihalcea
|
|
source_type: official-doc
|
|
status: raw
|
|
confidence: medium
|
|
url: https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#transactions
|
|
archive_url:
|
|
tags: [ca-persistence-failure, hibernate, jpa, osiv, lazy-loading, anti-pattern, official-doc]
|
|
related_branches: [feature-persistence-failure-baseline, feature-architecture-enforcement-rules]
|
|
related_projects: [ca-skeleton-operational-contract]
|
|
created: 2026-05-22
|
|
last_reviewed: 2026-05-27
|
|
---
|
|
|
|
# OSIV anti-pattern (Hibernate User Guide + Vlad Mihalcea)
|
|
|
|
> Layer: `raw/official-docs/` — Hibernate ORM User Guide + Vlad Mihalcea 의 OSIV anti-pattern 글 발췌. ca-tmpl persistence baseline 의 "OSIV off 가 기본" 결정의 외부 근거.
|
|
|
|
## Parent / 활용 branch (필수)
|
|
|
|
| Branch | 이 자료가 정당화하는 결정 |
|
|
|---|---|
|
|
| [[raw/branch-notes/feature-persistence-failure-baseline]] | "OSIV off 가 baseline default" 결정의 외부 근거 — view rendering 중 connection 점유로 인한 pool 고갈 / latency 증가 회피 |
|
|
| [[raw/branch-notes/feature-architecture-enforcement-rules]] | "presentation layer 에서 DB 접근이 발생하면 계약 위반" 이라는 architecture rule 의 정당화 — service layer 에서 fetch graph 명시 강제 |
|
|
|
|
특정 branch 없이 foundational 조사로 수집한 경우:
|
|
|
|
- [[raw/project-notes/ca-skeleton-operational-contract]] — ca-tmpl operational contract 의 persistence failure / architecture enforcement 초기 조사
|
|
|
|
## 컨텍스트 / 왜 저장했는지
|
|
|
|
ca-tmpl persistence baseline 의 핵심 결정 **"OSIV 는 off 가 기본"** 에 대한 외부 근거. presentation 에서 lazy loading 이 발생하면 계약 위반인 이유를 공식 / 권위 있는 출처로 확보.
|
|
|
|
## 출처 / Source
|
|
|
|
- 원본 URL: https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#transactions (Hibernate ORM User Guide — Transactions / Session management)
|
|
- 보조 URL: https://vladmihalcea.com/the-open-session-in-view-anti-pattern/ (Vlad Mihalcea — Hibernate developer advocate, OSIV anti-pattern 글)
|
|
- 아카이브 URL: (미수집)
|
|
- 저자 / 조직: Red Hat / Hibernate team; Vlad Mihalcea (Hibernate developer advocate, In Relation To 블로그 / Hibernate Performance 책 저자)
|
|
- 발행일: rolling docs / 블로그 게재 후 갱신
|
|
- 마지막 확인일: 2026-05-27 (WebFetch 시 vladmihalcea.com 및 hibernate.org 양쪽 모두 본 세션에서 permission denied — 인용은 원본 frontmatter 보존, 재검증 후속 라운드 필요)
|
|
- 보조 자료: Spring Boot `spring.jpa.open-in-view` 기본값 true 에 대한 startup warning 코드 (`JpaBaseConfiguration` source)
|
|
|
|
## 핵심 인용 / Key quotes (verbatim — 원본 frontmatter 보존)
|
|
|
|
> [Vlad Mihalcea, "The OpenSessionInView Anti-Pattern"] "Open Session in View (OSIV) is an anti-pattern. While it solves the LazyInitializationException, it does so by extending the database connection (and the JDBC transaction) until the view is rendered."
|
|
|
|
> [Vlad Mihalcea] "Holding the database connection during the view rendering is a serious performance issue. It increases the time the connection is taken from the pool, which can cause connection exhaustion under load."
|
|
|
|
> [Vlad Mihalcea] "Statements issued during the view layer are auto-committed, breaking the read-your-writes consistency and bypassing the service layer transaction boundary."
|
|
|
|
> [Spring Boot — `JpaBaseConfiguration` 의 startup WARN log] "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."
|
|
|
|
## Claims Extracted / 추출된 주장
|
|
|
|
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
|
|---|---|---|---|---|---|
|
|
| OSIV-AP-C1 | OSIV 는 LazyInitializationException 을 해결하는 대신 view rendering 까지 DB connection 과 JDBC transaction 을 연장하는 방식이며, Vlad Mihalcea 는 이를 anti-pattern 으로 명명 | [Vlad Mihalcea] "Open Session in View (OSIV) is an anti-pattern. While it solves the LazyInitializationException, it does so by extending the database connection (and the JDBC transaction) until the view is rendered." | `engineering-blog` | Hibernate / JPA + view layer (Thymeleaf, JSP, REST serializer 등) | "공식 Hibernate 문서가 OSIV 를 명시적으로 anti-pattern 으로 deprecate 했다" 는 뜻은 아님 — Vlad Mihalcea 는 Red Hat / Hibernate developer advocate 이지만 본 글은 그의 개인 블로그 |
|
|
| OSIV-AP-C2 | view rendering 동안 connection 을 점유하면 pool 점유 시간이 증가하고, 부하 상황에서 connection exhaustion 을 유발할 수 있음 (성능 이슈) | [Vlad Mihalcea] "Holding the database connection during the view rendering is a serious performance issue. It increases the time the connection is taken from the pool, which can cause connection exhaustion under load." | `engineering-blog` | OSIV on 으로 운영되는 Spring + JPA 애플리케이션 | 모든 시스템에서 반드시 connection exhaustion 이 발생한다는 보장 아님 — load 와 pool 크기 의존 |
|
|
| OSIV-AP-C3 | view layer 에서 발생한 statement 는 auto-commit 으로 처리되어 read-your-writes consistency 를 깨고 service layer transaction boundary 를 우회한다 | [Vlad Mihalcea] "Statements issued during the view layer are auto-committed, breaking the read-your-writes consistency and bypassing the service layer transaction boundary." | `engineering-blog` | OSIV on + view 단계에서 추가 SQL 발생 시나리오 | "auto-commit" 의 정확한 transactional 동작 (Spring TransactionManager 가 어떻게 처리하는지의 디테일) 은 본 인용 범위 밖 |
|
|
| OSIV-AP-C4 | Spring Boot 는 기본적으로 `spring.jpa.open-in-view=true` 이며, 명시적으로 disable 하지 않으면 startup 시 "spring.jpa.open-in-view is enabled by default... database queries may be performed during view rendering" WARN 로그를 출력한다 | [Spring Boot — JpaBaseConfiguration WARN log] "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." | `official-vendor-doc` | Spring Boot + Spring Data JPA 환경 | Spring Boot 가 future version 에서 default 를 false 로 변경할 계획이라는 뜻은 아님 — WARN 출력 자체만 보장 |
|
|
|
|
## Usage Boundaries / 적용 경계
|
|
|
|
- **이 자료가 직접 증명하는 것**:
|
|
- `OSIV-AP-C1` ~ `C3`: Vlad Mihalcea 가 제시한 OSIV anti-pattern 의 3가지 근거 (connection 점유 / auto-commit / transaction boundary 우회). **단, 이는 Hibernate developer advocate 의 권위 있는 blog 의견이며 Hibernate 또는 Spring 공식 문서의 공식적인 "anti-pattern 선언" 이 아님**
|
|
- `OSIV-AP-C4`: Spring Boot 가 OSIV default true 임을 인정하고 WARN 로그로 명시한다는 사실 (공식 vendor 코드 base 의 verbatim WARN)
|
|
- **이 자료가 증명하지 않는 것**:
|
|
- Hibernate ORM User Guide 자체가 OSIV 를 anti-pattern 으로 명시적으로 deprecate 했다는 사실 (본 세션에서는 hibernate.org WebFetch denied — 직접 verbatim quote 미확보)
|
|
- OSIV on 으로 운영해도 안전한 워크로드의 정확한 조건 (예: low traffic, read-only) 은 본 인용 범위 밖
|
|
- n+1 silent 문제가 OSIV 의 직접 효과인지 (n+1 은 OSIV 와 무관하게도 발생 가능 — OSIV 는 단지 silent 화)
|
|
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
|
- ca-tmpl 의 `spring.jpa.open-in-view=false` 설정이 실제로 startup assertion 으로 들어가 있는지 코드 검증
|
|
- 우리 service layer 가 fetch graph (`@EntityGraph` / `JOIN FETCH` / DTO projection) 를 일관성 있게 적용 중인지 코드 검증
|
|
- vladmihalcea.com 의 원문을 다음 세션에서 정확하게 verbatim 으로 재확인 (본 세션 WebFetch 차단)
|
|
- Hibernate User Guide 의 OSIV 관련 직접 인용을 후속 라운드에 확보 (현재는 frontmatter URL 만 있음)
|
|
|
|
## 메모 / Notes (내 프로젝트 해석 — 검증 전 추론)
|
|
|
|
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
|
|
|
|
- **왜 anti-pattern 인가 (해석 정리)**:
|
|
1. **connection pool 고갈** (`OSIV-AP-C2` 의 해석) — view rendering 동안 connection 점유. p99 latency 늘어남.
|
|
2. **n+1 silent** (Vlad 본문 추가 해석) — service 에서 fetch 안 한 association 이 view 에서 lazy load → SQL 폭증을 service 단위 테스트에서 못 잡음.
|
|
3. **transaction boundary 모호** (`OSIV-AP-C3`) — 추가 SQL 이 auto-commit 으로 새 단위로 나감.
|
|
- **ca-tmpl 결정과의 정합성**: "presentation 에서 DB 접근이 발생하면 계약 위반" 은 OSIV 끄고 service layer 에서 fetch graph 를 명시하라는 동일한 주장.
|
|
- **대안 (해석)**:
|
|
- `@EntityGraph` / explicit `JOIN FETCH` 로 service 에서 lazy association 을 미리 로드
|
|
- DTO projection (interface/class projection) 으로 presentation 에서 entity 를 안 쓰게
|
|
- **시사점**: Spring Boot 기본값이 `true` 라서 (`OSIV-AP-C4`) **명시적으로 `spring.jpa.open-in-view=false` 를 설정** 해야 함. ca-tmpl baseline 에 startup assertion 후보.
|
|
|
|
## Related / 관련
|
|
|
|
- 같은 주제 다른 official-doc / company-tech-blog:
|
|
- Hibernate User Guide §Transactions (frontmatter URL — 본 세션 verbatim 미확보)
|
|
- Spring Boot reference (별도 raw 후속 수집 권장 — `spring.jpa.open-in-view` 공식 property doc)
|
|
- 인용하는 branch:
|
|
- [[raw/branch-notes/feature-persistence-failure-baseline]]
|
|
- [[raw/branch-notes/feature-architecture-enforcement-rules]]
|
|
- 인용하는 wiki: (미작성 — `/ingest` 시 `wiki/concepts/osiv-anti-pattern` 후보)
|
|
- 대안 그룹 (ca-tmpl 결정 컨텍스트): **Group G-C — Persistence failure** (OSIV off vs OSIV on vs DTO projection 강제)
|