[Spring] JPA ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๊ตฌ์กฐ๋กœ ๋ณด๋Š” ์ด์ 

๋ฐ˜์‘ํ˜•

์ง€๋‚œ ํฌ์ŠคํŠธ์—์„œ JPA์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ ์ƒ๋ช… ์ฃผ๊ธฐ์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ์ƒ๋ช… ์ฃผ๊ธฐ์˜ ๊ด€๊ณ„๋ฅผ ํ†ตํ•ด์„œ Java๋กœ ๊ตฌํ˜„๋œ ๊ฐ์ฒด๊ฐ€ ์–ด๋–ป๊ฒŒ DB๋กœ ์ ์žฌ๋˜๊ณ  ์‚ญ์ œ๋˜๋Š”์ง€๋ฅผ ์•Œ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์™œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ผ๊นŒ์š”?

์ฒ˜์Œ์— ์ €๋Š” ์ด๋ ‡๊ฒŒ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. JDBC๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์–ด์ฐจํ”ผ Connection์ด ์ƒ์„ฑ๋˜์–ด์•ผ ํ•˜๊ณ , ๊ทธ์— ๋”ฐ๋ฅธ Statement๊ฐ€ ๋งŒ๋“ค์–ด์ ธ์•ผ ํ•˜๋Š”๋ฐ, ์„œ๋ฒ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŠน์„ฑ์ƒ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ, Connection์ด ์—ฌ๋Ÿฌ๊ฐœ ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— Connection Pool์ด๋ผ๋Š” ๊ฒƒ์ด ์žˆ๊ณ , ๋Œ€ํ‘œ์ ์œผ๋กœ HikariCP๊ฐ€ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์ฃ . ๊ทธ ๋‹ค์Œ์—๋Š” ์ฟผ๋ฆฌ๋ฌธ์„ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด ๋ถ€๋ถ„๊ณผ ํ•จ๊ป˜ ์ปค๋ฐ‹๊นŒ์ง€ ํ•ด์ฃผ๋Š” ๋…€์„์ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ผ๊ณ  ์ƒ๊ฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋Œ€์ถฉ ๊ทธ๋Ÿด์‹ธํ•˜์ง€๋งŒ ์ง„์งœ ๋ชฉ์ ์€ ๋”ฐ๋กœ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค..

 

 

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ์ด์  1: Cache

๋จผ์ € ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” Entity๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅํ•˜๋Š” ํ™˜๊ฒฝ์ด๋ผ๊ณ  ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฆ‰, DB์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ EntityManager ๋ฅผ ์ด์šฉํ•ด์„œ Entity๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—๋Š” 1์ฐจ ์บ์‹œ๋ผ๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. Entity๊ฐ€ DB์— ์ €์žฅ๋˜๊ธฐ ์ „์— ์‚ฌ์šฉ๋˜๋Š” ๊ณต๊ฐ„์ธ๋ฐ, ๋ฐ˜๋Œ€๋กœ DB๋ฅผ ์กฐํšŒํ•˜๊ณ  ๋‚  ๋•Œ์—๋„ ์ €์žฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•œ ๋ฒˆ ๋” ๊ฐ™์€ Entity๋ฅผ ์ฝ๊ณ ์ž ํ•  ๋•Œ ๋น ๋ฅธ ์ฝ๊ธฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ๋ถ€ํ•˜๋ฅผ ์ค„์—ฌ์ค๋‹ˆ๋‹ค.

 

Cafe americano = new Cafe();
cafe.setName("Americano");
cafe.setPrice(3000);

Cafe espresso = new Cafe();
cafe.setName("Espresso");
cafe.setPrice(3000);

Cafe cafuchino = new Cafe();
cafe.setName("Cafuchino");
cafe.setPrice(4000);

// ์บ์‹œ์— ์ €์žฅ๋จ
em.persist(americano);
em.persist(espresso);
em.persist(cafuchino);

// ์บ์‹œ์—์„œ ์กฐํšŒ
em.find(Cafe.class, 1);

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” 2์ฐจ ์บ์‹œ๊นŒ์ง€ ์กด์žฌํ•˜์ง€๋งŒ ๋…๋ฆฝ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์€ 1์ฐจ ์บ์‹œ์ด๋ฉฐ 2์ฐจ ์บ์‹œ์˜ ๊ฒฝ์šฐ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด Entity์— ์‚ฌ์šฉํ•˜๋Š” ์บ์‹œ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ 2์ฐจ ์บ์‹œ๋Š” ์กด์žฌํ•˜์ง€๋งŒ Entity์˜ Transaction Thread๊ฐ€ ์ข…๋ฃŒ๋˜๋Š” ๊ฒฝ์šฐ, 1์ฐจ ์บ์‹œ๋Š” ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„ ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ์งง์€ ์บ์‹œ์ž…๋‹ˆ๋‹ค.

DB์—์„œ ์กฐํšŒํ•  ๋•Œ

  • 1์ฐจ ์บ์‹œ๋ฅผ ๋จผ์ € ์กฐํšŒํ•œ ํ›„, ์žˆ์œผ๋ฉด 1์ฐจ ์บ์‹œ์˜ ๋‚ด์šฉ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
  • 1์ฐจ ์บ์‹œ์—์„œ Entity๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์„ ๊ฒฝ์šฐ, 2์ฐจ ์บ์‹œ์—์„œ ์กฐํšŒํ•˜๋ฉฐ ์—ฌ๊ธฐ์—๋„ ์—†๋‹ค๋ฉด, DB์—์„œ ์กฐํšŒํ•œ๋‹ค.
  • DB์—์„œ ์กฐํšŒํ•œ Entity๋ฅผ 1์ฐจ ์บ์‹œ์™€ 2์ฐจ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.
  • ์กฐํšŒํ•œ Entity๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

DB์—์„œ ์กฐํšŒํ–ˆ์„ ๋•Œ๋งŒ์œผ๋กœ๋„ 1์ฐจ ์บ์‹œ์— ์ €์žฅ๋˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์‹œ๊ธˆ ์ด ์š”์ฒญ์„ ์ง„ํ–‰ํ–ˆ์„ ๋•Œ ์บ์‹œ์—์„œ ๋น ๋ฅด๊ฒŒ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์ฒซ ๋ฒˆ์งธ ์ด์ ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

DB์— ์ €์žฅํ•  ๋•Œ

  • ๊ฐ์ฒด๋กœ ๋งŒ๋“  Entity๋ฅผ ์˜์† ์ƒํƒœ๋กœ ์ „ํ™˜ํ•˜๋ฉด 1์ฐจ ์บ์‹œ์™€ 2์ฐจ ์บ์‹œ์— ์ €์žฅ๋œ๋‹ค. (DB์— ์—†์Œ)
  • 1์ฐจ ์บ์‹œ์— ์ €์žฅ๋œ Entity๋Š” ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด DB๋กœ ์ €์žฅ๋œ๋‹ค.
  • ์ž‘์—…์ด ๋๋‚ฌ์œผ๋ฉด ์ค€์˜์† ์ƒํƒœ๋กœ ์ „ํ™˜ํ•œ๋‹ค.

๋ฒˆ๊ฑฐ๋กœ์šด ๋ฉด์€ ์žˆ์ง€๋งŒ 1์ฐจ ์บ์‹œ์— ์ €์žฅ๋จ์œผ๋กœ์จ ์ค‘๊ฐ„์— ์ˆ˜์ •ํ•  ์‚ฌํ•ญ์ด ์žˆ๋‹ค๋ฉด UPDATE ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ INSERT ์ฟผ๋ฆฌ๋งŒ์œผ๋กœ ๋ฐ”๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ๋„ ๋‚˜๋ฆ„์˜ ์ด์ ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ์‹์œผ๋กœ 1์ฐจ ์บ์‹œ๋Š” Entity๋งˆ๋‹ค ๋…๋ฆฝ๋œ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•˜๋ฉฐ ๋งŒ์•ฝ, 1,000๋ช… ์ •๋„์˜ ์‚ฌ์šฉ์ž๊ฐ€ DB ์š”์ฒญ์ด ์˜ค๋ฉด EntityManager๊ฐ€ 100๊ฐœ ์ƒ์„ฑ๋˜๋ฉฐ Thread๊ฐ€ ์ข…๋ฃŒ๋œ ๋’ค์—๋Š” ๋ชจ๋‘ ์†Œ๋ฉธ๋ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋Œ€๋กœ 2์ฐจ ์บ์‹œ๋Š” Application ์ „์ฒด์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์บ์‹œ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ณ„์† ์œ ์ง€๋˜๋Š” ์บ์‹œ์ž…๋‹ˆ๋‹ค. JPA 2.0์—์„œ๋ถ€ํ„ฐ ํ‘œ์ค€์ด ๋˜์—ˆ์œผ๋ฉฐ Hibernate์˜ 2์ฐจ ์บ์‹œ์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋Š”๋ฐ, ๊ตฌ์ฒด์ ์ธ ๋‚ด์šฉ์€ Hibernate 2์ฐจ ์บ์‹œ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ฐจํ›„์— ํฌ์ŠคํŠธํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ ์ด์  2: ๋™์ผ์„ฑ ๋ณด์žฅ

์บ์‹œ์—์„œ ํ•œ ๋ฒˆ ์„ค๋ช…์„ ๋“œ๋ ธ์ง€๋งŒ, Entity๋ฅผ DB์— ์ €์žฅํ•  ๋•Œ, ์บ์‹œ์— ํ•œ ๋ฒˆ ๋ณด๊ด€์„ ํ•œ๋‹ค๊ณ  ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด ๋ง์€ ์บ์‹œ์— ์žˆ๋Š” ๊ฒƒ๊ณผ ์‹ค์ œ DB์— ์กด์žฌํ•˜๋Š” ๊ฒƒ์ด ๊ฐ™์œผ๋ฉด์„œ ๋ ˆํผ๋Ÿฐ์Šค ๊ด€๊ณ„๊ฐ€ ๋œ๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ์š”. ์ฆ‰, ์บ์‹œ์— ๋ณด๊ด€ํ•˜๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ์™€ DB์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ 100% ๋™์ผํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์—์„œ persist ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, Entity๋“ค์„ 1์ฐจ ์บ์‹œ์— ์ƒ์„ฑํ•˜๊ณ , ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” Write-behind SQL ์ €์žฅ์†Œ์— INSERT ์ฟผ๋ฆฌ ๋“ฑ์˜ DML ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์Œ“์•„๋†“์Šต๋‹ˆ๋‹ค.

์ตœ์ข…์ ์œผ๋กœ commit() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์ € ์ €์žฅ์†Œ์— ์žˆ๋Š” ๋ชจ๋“  ์ฟผ๋ฆฌ๊ฐ€ DB๋กœ ์ „๋‹ฌ๋˜๋ฉฐ ์ด ๋•Œ๋ถ€ํ„ฐ DB์— ๋‚ด์šฉ์ด ๋ฐ˜์˜๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, ์—ฌ๊ธฐ์—์„œ ํ•จ์ •์€ commit() ๋ฉ”์†Œ๋“œ ๋‚ด์—๋Š” flush() ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ™์ด ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. flush() ๋ฉ”์†Œ๋“œ๋Š” Write-behind SQL ์ €์žฅ์†Œ์— ์žˆ๋Š” ๋ชจ๋“  ์ฟผ๋ฆฌ๋ฅผ DB์— ์ „์†กํ•˜๋Š” ๋ฉ”์†Œ๋“œ์ด๊ณ , ๊ทธ ๋‚ด์šฉ์„ ๋ฐ˜์˜ํ•˜๋Š” ๊ฒƒ์ด commit() ๋ฉ”์†Œ๋“œ์ธ๋ฐ, ์‹ค์ œ ํŠธ๋žœ์žญ์…˜ ๋‚ด์˜ commit์€ ์ด 2๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ์ˆ˜ํ–‰ํ•œ๋‹ค๋Š” ์ ์„ ์ธ์ง€ํ•˜์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();

// ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋Š” ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์‹œ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.
transaction.begin(); // ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘

em.persist(americano);

// ์ปค๋ฐ‹ํ•˜๋Š” ์ˆœ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— INSERT SQL์„ ๋ณด๋‚ธ๋‹ค.
// ์ด ๋•Œ flush()์™€ commit()์ด ๊ฐ™์ด ์‹คํ–‰๋จ
transaction.commit();

๊ทธ๋ ‡๋‹ค๋ฉด Write-behind SQL ์ €์žฅ์†Œ์— SQL ์ฟผ๋ฆฌ๊ฐ€ 100๊ฐœ ์Œ“์ด๋ฉด 100๊ฐœ๊ฐ€ ํ•œ๊บผ๋ฒˆ์— ์ „์†ก๋˜๋Š” ๊ฑธ๊นŒ? SQL ์ €์žฅ์†Œ์— ์ตœ๋Œ€๋กœ ์Œ“์ผ ์ˆ˜ ์žˆ๋Š” SQL ๊ฐฏ์ˆ˜๋Š” 30๊ฐœ์ด๋ฉฐ application.yml ํŒŒ์ผ ๋“ฑ์„ ํ†ตํ•ด์„œ hibernate batch size๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

spring.jpa.properties.hibernate.jdbc.batch_size=20

 

 

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์ด์  3: ์—”ํ‹ฐํ‹ฐ ์ˆ˜์ •์‹œ ์ž‘๋™ํ•˜๋Š” Dirty Checking

Entity๋ฅผ ์ˆ˜์ •ํ•ด์•ผํ•  ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„๊นŒ? ๊ทธ๋ƒฅ ์šฐ๋ฆฌ๊ฐ€ JPA๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ , ์ฝ”๋“œ๋ฅผ ์งœ๋ณธ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์งค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// EntityManager ์ƒ์„ฑ
EntityManager em = emf.createEntityManager();

// ์˜์† Entity ์กฐํšŒ
Cafe cafe = em.find(Cafe.class, 1);

// ์˜์† Entity ์ˆ˜์ •
cafe.setName("iceAmericano");

์ด๋ ‡๊ฒŒ ์งœ๊ณ  commit()๋งŒ ์ˆ˜ํ–‰ํ•˜๋ฉด ์•Œ์•„์„œ ๋ ๊นŒ? ๊ทธ๋Ÿฐ๋ฐ, ์šฐ๋ฆฌ๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์žˆ๋Š” Entity๋ฅผ transaction beginํ•˜๊ณ  commitํ•˜๋ฉด INSERT ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€๋Š” ๊ฒƒ์œผ๋กœ ์•Œ๊ณ  ์žˆ๋Š”๋ฐ, ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ƒˆ๋กœ์šด Row๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹๊นŒ?

// EntityManager ์ƒ์„ฑ
EntityManager em = emf.createEntityManager();

// ์˜์† Entity ์กฐํšŒ
Cafe cafe = em.find(Cafe.class, 1);

// ์˜์† Entity ์ˆ˜์ •
cafe.setName("iceAmericano");

// ํŠธ๋žœ์žญ์…˜ ์ƒ์„ฑ ๋ฐ ์ปค๋ฐ‹
EntityTransaction transaction = em.getTransaction();
transaction.begin();
transaction.commit();

์ •๋‹ต์€ INSERT๊ฐ€ ์•„๋‹Œ UPDATE ์ฟผ๋ฆฌ๊ฐ€ ์ž˜ ์‹คํ–‰๋œ๋‹ค ์ž…๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ๊ฑธ๊นŒ์š”? ๊ทธ๋ƒฅ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์บ์‹œ์— Entity๋ฅผ ๋ถˆ๋Ÿฌ์™”์„ ๋ฟ์ด๊ณ , ์šฐ๋ฆฌ๊ฐ€ ์•Œ๋˜๋Œ€๋กœ๋ผ๋ฉด INSERT ์ฟผ๋ฆฌ๊ฐ€ ์ƒ์„ฑ๋˜์–ด DB์— ๋ณด๋‚ด์ ธ์•ผํ• ํ…๋ฐ ๋ง์ด์ฃ .

 

๊ทธ ๋น„๋ฐ€์€ JPA ์บ์‹œ์— ์žˆ๋Š” ์Šค๋ƒ…์ƒท ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 1์ฐจ ์บ์‹œ์— ์ €์žฅํ•  ๋•Œ ID์™€ Entity, ๊ทธ๋ฆฌ๊ณ  Snapshot์ด ์ €์žฅ๋˜๋Š”๋ฐ, commit() ๋˜๋Š” flush()๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ Snapshot์„ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ผ ๊ฒฝ์šฐ์—๋Š” UPDARE ์ฟผ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฐ์ง€ํ•˜๋Š” ๊ธฐ์ˆ ์„ ์šฐ๋ฆฌ๋Š” Dirty Checking์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. 

๊ทธ๋Ÿฐ๋ฐ, ์šฐ๋ฆฌ๊ฐ€ ๋‹จ์ˆœํžˆ Setter ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝํ•˜๋ฉด UPDATE ์ฟผ๋ฆฌ๋ฅผ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์€ ๋งž์ง€๋งŒ ๋ชจ๋“  ํ•„๋“œ์— ๋Œ€ํ•ด์„œ ๋ณ€๊ฒฝ ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ Entity์˜ ํ•„๋“œ๊ฐ€ 20๊ฐœ ์ด์ƒ์ด๋ผ๋ฉด 20๊ฐœ ์ด์ƒ์„ ๋ชจ๋‘ ๋ฐ˜์˜ํ•˜๋Š” ๊ฒƒ์ด์ฃ . 

์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋ฉด ์ฟผ๋ฆฌ๊ฐ€ ๊ธธ์–ด์ง€๊ณ , ๋””๋ฒ„๊น…์ด ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด์„œ๋งŒ UPDATE ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์—๋Š” @DynamicUpdate ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. 

์œ„ Annotation์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์›ํ•˜๋Š” ํ•„๋“œ์— ๋Œ€ํ•ด์„œ๋งŒ UPDATE ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๋งˆ์น˜๋ฉฐ...

์—ฌ๊ธฐ๊นŒ์ง€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๊ตฌ์กฐ๋กœ ๋ณด๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ ์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค. ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ์ œ๊ณตํ•˜๋Š” ์บ์‹œ๋ฅผ ์ด์šฉํ•ด Dirty Checking์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ Java ์ ์ธ ๋ฐฉ๋ฒ•์„ ์ธ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋ผ ์•„์ฃผ ๊ดœ์ฐฎ๋‹ค๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋งŽ์ด ๊ฐ€์ง€๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 

๊ทธ๋Ÿฌ๋‚˜ UPDATE ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ, ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด์„œ๋งŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒŒ ๊ธฐ๋ณธ๊ฐ’์ด๋ผ๋ฉด ์ข‹์•˜์„ํ…๋ฐ, ๊ทธ๋ ‡์ง€ ์•Š์€ ์ด์œ ๋Š” ์•„๋งˆ ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง€๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์„๊นŒ ์˜ˆ์ƒํ•ด๋ด…๋‹ˆ๋‹ค. 

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments