OSIV

๊ฒฐ๋ก ๋ถ€ํ„ฐ ์–˜๊ธฐํ•˜๋ฉด OSIV๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ View๊นŒ์ง€ ์—ด์–ด๋‘๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

  • Springboot ์—๋Š” spring.jpa.open.in-view๋ผ๋Š” ์˜ต์…˜์ด ์žˆ๋‹ค. (true/false)

  • default๋Š” true์ด๋‹ค.

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ์–ธ์ œ ์ƒ๊ธฐ๊ณ  ์–ธ์ œ ์‚ฌ๋ผ์งˆ๊นŒ?

ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ

์„œ๋น„์Šค์˜ ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋˜๋ฉด์„œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ณ  ์—”ํ‹ฐํ‹ฐ๋Š” ์˜์† ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋  ๋•Œ ๋งŒ๋“ค์–ด์ง€๊ณ  ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋œ ํ›„ ์‚ฌ๋ผ์ง„๋‹ค.

์„œ๋น„์Šค๊ฐ€ ๋๋‚˜๊ณ  ํŠธ๋žœ์žญ์…˜์—์„œ ๋‚˜์˜ค๋ฉด ์ค€์˜์† ์ƒํƒœ๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ•˜๋Š” ์‹œ์ ์— ์ƒ์„ฑ๋˜์ง€๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ฐ๋Š” DB ํŠธ๋žœ์žญ์…˜์€ ๋น„์ฆˆ๋‹ˆ์Šค ๋ ˆ์ด์–ด์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋„๋ก ํŠธ๋žœ์žญ์…˜์ด ๋ฐœ์ƒํ•œ๋‹ค.

๊ทธ๋ž˜์„œ OSIV๊ฐ€ ๋ญ๋ƒ๋ฉด ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๋„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ DB ์ปค๋„ฅ์…˜์„ ์‚ด๋ ค๋‘๋Š” ๊ฒƒ์ด๋‹ค.

API์˜ ๊ฒฝ์šฐ์—๋Š” ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•  ๋•Œ๊นŒ์ง€, ํ™”๋ฉด์˜ ๊ฒฝ์šฐ ๋ทฐ ํ…œํ”Œ๋ฆฟ์„ ๋ Œ๋”๋ง ํ•  ๋•Œ๊นŒ์ง€

๊ฒฐ๊ตญ, ์œ ์ €์—๊ฒŒ response ํ•  ๋•Œ๊นŒ์ง€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ DB ์ปค๋„ฅ์…˜์ด ๊ณ„์† ์‚ด์•„์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

OSIV์˜ ์ตœ๋Œ€ ์žฅ์ ์€ ์ปจํŠธ๋กค๋Ÿฌ๋‚˜ ๋ทฐ์—์„œ๋„ Entity๋ฅผ Lazy ๋กœ๋”ฉํ•ด์„œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

OSIV-false

OSIV=false
  • ํŠธ๋žœ์žญ์…˜์„ ์ข…๋ฃŒํ•  ๋•Œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๋‹ซ๊ณ  DB ์ปค๋„ฅ์…˜์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    • ๋ฐ˜ํ™˜ํ•˜๊ณ  ๋‚˜์„œ DB ์ปค๋„ฅ์…˜์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

  • ๋ชจ๋“  ์ง€์—ฐ ๋กœ๋”ฉ์„ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ํ•ด๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

    • ์ง€์—ฐ ๋กœ๋”ฉ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์‚ด์•„์žˆ์–ด์•ผ ํ•œ๋‹ค.

    • ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋˜๊ธฐ ์ „์— ์ง€์—ฐ ๋กœ๋”ฉ์„ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ fetch join์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, User์™€ ๋งคํ•‘๋œ Review๊ฐ€ ์กด์žฌํ•œ๋‹ค. OSIV๋ฅผ ๋„๊ณ  Controller์—์„œ User๋กœ Review๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

could not initialize proxy ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๊ทธ ์ด์œ ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋˜๊ณ  ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋ก์‹œ๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ์ˆ˜ ์—†๋‹ค. Review๋ฅผ Lazy Loading ํ•˜์ง€๋งŒ User๋Š” ์ค€์˜์† ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

OSIV๋ฅผ ๋„๊ณ  ์œ„ API๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด review.getUser().getName() ์—์„œ Could not initalize proxy no Session์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. getUser()๋Š” ํ”„๋ก์‹œ์ธ๋ฐ ์•„์ง ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ getName()์„ ํ˜ธ์ถœํ•˜๋Š” ์ˆœ๊ฐ„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ํ”„๋ก์‹œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•˜๋Š”๋ฐ ์—ฌ๊ธฐ์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” fetch join์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋˜๋Š”๋ฐ, ์ฒ˜์Œ๋ถ€ํ„ฐ ์„ค๊ณ„๋ฅผ ์ž˜ ํ•œ๋‹ค๋ฉด ์ด ๋ถ€๋ถ„์€ ์ด๋ฏธ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์•„๋„ ๋  ๊ฒƒ์ด๋‹ค. ๋‹ค์‹œ ํ•œ๋ฒˆ ์„ค๊ณ„๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ ๋ฅผ ์•Œ ๊ฒƒ ๊ฐ™๊ธฐ๋„ํ•˜๋‹ค.

OSIV-true

OSIV=true
  • ํŠธ๋žœ์žญ์…˜ ๋ฐ–์—์„œ๋„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์กด์žฌํ•˜์—ฌ DB ์ปค๋„ฅ์…˜์„ ์œ ์ง€ํ•˜๊ณ  ์žˆ๋‹ค.

    • ์ฆ‰, API ์‘๋‹ต ํ›„ ํ™”๋ฉด์ด ๋ Œ๋”๋ง ๋  ๋•Œ๊นŒ์ง€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๋ฌผ๊ณ  ์žˆ๋Š”๋‹ค.

  • DB ์ปค๋„ฅ์…˜์„ ๊ณ„์† ๋ฌผ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์‹œ๊ฐ„ ํŠธ๋ž˜ํ”ฝ์ด ์ค‘์š”ํ•œ ์„œ๋น„์Šค์—์„œ๋Š” ์ปค๋„ฅ์…˜์ด ๋ถ€์กฑํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Controller์—์„œ๋„ ์ง€์—ฐ ๋กœ๋”ฉ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

  1. ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด Servlet Filter๋‚˜ Spring Interceptior์—์„œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ(Entity Manager)๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ---> ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๊ณ  ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

  2. Service Layer์—์„œ ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘ํ•  ๋•Œ ๊ธฐ์กด์— ์ƒ์„ฑ๋œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•œ๋‹ค.

  3. Service ๋กœ์ง์ด ๋๋‚˜๋ฉด ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•˜๊ณ  ์ข…๋ฃŒํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ์†Œ๋ฉธ๋˜์ง€ ์•Š๋Š”๋‹ค. ---> DB ์ปค๋„ฅ์…˜์ด ์•„์ง ์ข…๋ฃŒ๋˜์ง€ ์•Š์•˜๋‹ค.

  4. Controller์™€ View์—์„œ๋„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์œ ์ง€๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ๋œ Entity๋Š” ์˜์† ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•œ๋‹ค.

  5. Servlet Filter ํ˜น์€ Spring Interceptor๋กœ ๋กœ์ง์ด ๋‹ค์‹œ ํšŒ๊ท€๋œ ๊ฒฝ์šฐ, ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค. ---> ์ด ๋•Œ, flush ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹Œ close๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

3๋ฒˆ ์ดํ›„์—๋Š” Controller๋ถ€ํ„ฐ Entity๊ฐ€ ์ˆ˜์ • ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๊ฐ€ ๋˜๋Š”๋ฐ, ์ด ๋•Œ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋œ ์ƒํƒœ์ด๋‹ค.

ํ•˜์ง€๋งŒ Entity๋ฅผ ์ˆ˜์ •/์‚ญ์ œ ํ•˜๋Š” ์ž‘์—…์ด ์•„๋‹ˆ๋ผ ์กฐํšŒ๋Š” ์•„๋ฌด๋Ÿฐ ์ƒ๊ด€์ด ์—†๋‹ค.

๋”ฐ๋ผ์„œ Entity ๊ฐ์ฒด๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ณผ์ •์—์„œ ์ง€์—ฐ ๋กœ๋”ฉ์ด ๋ฐœ์ƒํ•ด๋„ ์กฐํšŒ๋งŒ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Controller์—์„œ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ---> JPA๋ฅผ ์‚ฌ์šฉํ•ด์„œ Entity๋ฅผ ์ˆ˜์ •/์‚ญ์ œํ•˜๋Š” ํ–‰์œ„๋Š” ๋ฐ˜๋“œ์‹œ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„์—์„œ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” ๋ณ€๊ฒฝ ๊ฐ์ง€(Dirty Checking) ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์„œ ํŠธ๋žœ์žญ์…˜ ๋ฐ–์—์„œ ์ˆ˜์ •/์‚ญ์ œ๋ฅผ ์‹œ๋„ํ•œ๋‹ค๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ์ˆ˜์ •๋˜์ง€ ์•Š๋Š”๋‹ค.

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ DB์— ๋ฐ˜์˜ํ•˜๋ ค๋ฉด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ flush ํ•ด์•ผํ•˜๋Š”๋ฐ, Spring์ด ์ œ๊ณตํ•˜๋Š” OSIV ์š”์ฒญ์ด ๋๋‚˜๋ฉด flush๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ , close ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฏ€๋กœ Entity์˜ ๋ณ€๊ฒฝ์„ DB์— ๋ฐ˜์˜ํ•˜์ง€ ์•Š๊ณ  ์ข…๋ฃŒํ•จ.

  • ๊ฐ•์ œ๋กœ DI๋ฅผ ์ด์šฉํ•ด์„œ Spring์˜ EntityManager๋ฅผ ์‚ฌ์šฉํ•ด์„œ flush๋ฅผ ํ˜ธ์ถœํ•ด๋„ ์ด๋ฅผ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋กœ ๋ง‰์•„๋ฒ„๋ฆฌ๋Š” ์ฝ”๋“œ ๋•Œ๋ฌธ์— ์•ˆ๋จ.

OSIV๋ฅผ ์–ธ์ œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„๊นŒ?

OSIV๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ

  • ์„œ๋น„์Šค์˜ ํŠธ๋ž˜ํ”ฝ์ด ๋งŽ์€ ์‹ค์‹œ๊ฐ„ API

  • Controller์™€ Service๊ฐ€ 1:1 ๋งคํ•‘์ธ ๊ฒฝ์šฐ

  • Service์—์„œ ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋˜๋Š” ๊ฒฝ์šฐ

OSIV๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

  • View์—์„œ Entity ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ Œ๋”๋ง ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ (Spring MVC)

  • View์—์„œ Entity ์—ฐ๊ด€ ๊ฐ์ฒด๋ฅผ ์ œ์–ดํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ

  • ๊ฐ™์€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์„ ๊ณต์œ ํ•˜๋Š” ๊ฒฝ์œ 

Spring MVC์˜ ๊ฒฝ์šฐ Entity๋ฅผ Service ๊ณ„์ธต ์œ„๊นŒ์ง€ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ํŠธ๋žœ์žญ์…˜์„ ๊ณต์œ ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

๊ทธ๋Ÿฐ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด OSIV ์‚ฌ์šฉ์€ DB ์ปค๋„ฅ์…˜์„ ์˜ค๋ž˜ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์–ด ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

Last updated