๐ŸŒฑ Entity์˜ ์ƒํƒœ (์ƒ๋ช… ์ฃผ๊ธฐ)

JPA์—์„œ ์—”ํ‹ฐํ‹ฐ๋Š” ํฌ๊ฒŒ 4๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์ƒํƒœ๋ฅผ ์ „ํ™˜์‹œํ‚ค๋Š” ๊ธฐ๋Šฅ์„ EntityManager๊ฐ€ ์ œ๊ณตํ•œ๋‹ค.

1. Transient(๋น„์˜์†): ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๊ฐ€ Java ๋ฉ”๋ชจ๋ฆฌ์—์„œ๋งŒ ์กด์žฌํ•˜๊ณ , ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ ์•„๋ฌด ๊ด€๋ จ ์—†๋Š” ์ƒํƒœ

2. Persistent(์˜์†): ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๊ฐ€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ๊ด€๋ฆฌ๋œ ์ƒํƒœ(์˜์† ์ƒํƒœ๋ผ๊ณ  ๋ฐ”๋กœ DB์— ์ฟผ๋ฆฌ๊ฐ€ ๋‚ ๋ผ๊ฐ€๋Š” ๊ฒƒ X)

3. Detached(์ค€์˜์†): ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๊ฐ€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅ๋˜์—ˆ๋‹ค๊ฐ€ ๋ถ„๋ฆฌ๋œ ์ƒํƒœ

4. Removed(์‚ญ์ œ): ์‹ค์ œ DB ์‚ญ์ œ๋ฅผ ์š”์ฒญํ•œ ์ƒํƒœ

 

๐ŸŒฑ Hibernate JPA EntityManager ํ•ต์‹ฌ ๊ธฐ๋Šฅ

1๏ธโƒฃ Persist

persist๋Š” ์—”ํ‹ฐํ‹ฐ์˜ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

Person person = new Person(name); // Transient/New
em.persist(person);   // Managed

์ฒ˜์Œ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ ํ•ด๋‹น ๊ฐ์ฒด๋Š” Transiend/New ์ƒํƒœ๋กœ ๋ถˆ๋ฆฐ๋‹ค.

persist ์—†์ด ๋ฐ”๋กœ Transaction์„ ์ข…๋ฃŒํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ƒ์—๋Š” ์•„๋ฌด ๋ณ€ํ™”๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

 

์ด ์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๊ด€๋ฆฌํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” persist ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋ฉฐ, ํ•ด๋‹น ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๋’ค persion์€ Managed ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

 

์ด๋Ÿฐ Managed ์ƒํƒœ์˜ ์—”ํ‹ฐํ‹ฐ๋“ค์€ EntityManager์— ์˜ํ•ด Dirty Check(๋ณ€๊ฒฝ ๊ฐ์ง€)๊ฐ€ ๋˜์–ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๋‚ด์˜ ๋‚ด์šฉ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ˜์˜ํ•˜๋Š” flush ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ, ๋ณ€๊ฒฝ๋œ ํ•„๋“œ์— ๋Œ€ํ•ด ์ž๋™์œผ๋กœ update/insert๋ฌธ์ด ๋ฐœํ–‰๋œ๋‹ค.

 

2๏ธโƒฃ Detach

entityManager.detach(person);
person.setName(anotherName); // will not saved automatically

์—”ํ‹ฐํ‹ฐ๊ฐ€ Managed์ธ ์ƒํƒœ์—์„œ detach ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ ํ•ด๋‹น ์—”ํ‹ฐํ‹ฐ๋Š” Detached ์ƒํƒœ๊ฐ€ ๋˜์–ด ๋” ์ด์ƒ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์˜ํ•ด ๊ด€๋ฆฌ๋ฅผ ๋ฐ›์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ, ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋˜๋”๋ผ๋„ detach ๋œ ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•œ ์ž๋™์ ์ธ ์ƒ์„ฑ/์ˆ˜์ • ์ž‘์—…์€ ์ „ํ˜€ ์ผ์–ด๋‚˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.

 

Person person = entityManager.find(Person.class, 1L);
entityManager.detach(person);

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ id๊ฐ€ 1L์ธ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์žˆ๊ณ  ์ด๋ฅผ find๋กœ ์ฐพ์•„์˜จ ๊ฒฝ์šฐ, ์ด ๊ฐ์ฒด๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” ์ค‘์ด๋ฏ€๋กœ, Managed ์ƒํƒœ์ด๋‹ค.

ํ•˜์ง€๋งŒ detach ๋ฉ”์„œ๋“œ๋กœ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ ๊ด€๊ณ„๋ฅผ ๋Š์œผ๋ฉด ํ•ด๋‹น persion ๊ฐ์ฒด๋Š” Detached ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

(Detached ๋˜์–ด๋„, ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๋‚ด์— ์žˆ๋˜ ๋‚ด์šฉ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ •์ƒ์ ์œผ๋กœ ๋ฐ˜์˜๋œ๋‹ค.)

 

detach๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๋Š” ์ „ํ˜€ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ , ์–ด๋–ค ์—”ํ‹ฐํ‹ฐ ์ธ์Šคํ„ด์Šค๋ฅผ '์˜คํ”„๋ผ์ธ' ์ƒํƒœ๋กœ ๋งŒ๋“ ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.(์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—๋Š” ์—ฌ์ „ํžˆ ์˜จ๋ผ์ธ ์ƒํƒœ์˜ ์—”ํ‹ฐํ‹ฐ ์กด์žฌ)

 

3๏ธโƒฃ Merge

merge๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์žˆ๋Š” ์—”ํ‹ฐํ‹ฐ์˜ ์ƒํƒœ๋ฅผ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋Š” ์—”ํ‹ฐํ‹ฐ ์ธ์Šคํ„ด์Šค์˜ ์ƒˆ ํ•„๋“œ ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

Person person = new Person(id, content);
entityManager.merge(person);

merge๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

- merge() ์‹คํ–‰

- ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜์–ด์˜จ ์ค€์˜์† ์—”ํ‹ฐํ‹ฐ์˜ ID ๊ฐ’์œผ๋กœ 1์ฐจ ์บ์‹œ์—์„œ ์—”ํ‹ฐํ‹ฐ ์กฐํšŒ
   โ†’ 1์ฐจ ์บ์‹œ์— ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์—†์œผ๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  1์ฐจ ์บ์‹œ์— ์ €์žฅ

- ์กฐํšŒํ•œ ์˜์† ์—”ํ‹ฐํ‹ฐ(mergePerson)์— person ์—”ํ‹ฐํ‹ฐ์˜ ๊ฐ’ ์ฑ„์›Œ ๋„ฃ์Œ

- ์˜์† ์ƒํƒœ์ธ mergePerson ๋ฐ˜ํ™˜

 

persist()๋Š” return ๊ฐ’์ด ์—†์ง€๋งŒ, ์ „๋‹ฌ๋œ ์ธ์Šคํ„ด์Šค๊ฐ€ managed ๋œ๋‹ค.

merge()๋Š” ์ „๋‹ฌ๋œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์—ฌ์ „ํžˆ Detached ์ƒํƒœ์ธ ๋Œ€์‹  Managed ์ƒํƒœ์ธ ์ธ์Šคํ„ด์Šค๋ฅผ return ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ merge()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ ๋ฆฌํ„ด๋œ ๊ฒฐ๊ณผ๋ฅผ ํ†ตํ•ด ๋‹ค์Œ ์ž‘์—…์„ ์ง„ํ–‰ํ•ด์•ผ entityManager๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ์ƒํƒœ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

4๏ธโƒฃ Remove

remove๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์‚ญ์ œ๋˜๊ธฐ๋ฅผ ์›ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

em.remove(comment); // will removed from db

์ด ๊ฒฝ์šฐ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ์ œ๊ฑฐ๋˜๊ณ  ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ญ์ œ๋„ ๋œ๋‹ค.

 

 

 

 

Hibernate JPA EntityManager ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์ •๋ฆฌ

persist, detach, merge, remove์˜ ๋‹ค์–‘ํ•œ ์‚ฌ๋ก€

tech.junhabaek.net

 

JPA EntityManager: Why use persist() over merge()?

EntityManager.merge() can insert new objects and update existing ones. Why would one want to use persist() (which can only create new objects)?

stackoverflow.com