๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŒท Spring/๊ฐœ๋…

[Spring][JPA] OrphanRemoval=true์— ๋Œ€ํ•ด์„œ ์‰ฝ๊ฒŒ ์•Œ์•„๋ณด์ž!

by hyeong._.ing 2026. 6. 10.

 

 

๋ณดํ†ต ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ์™€ ์ž์‹ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ
OrphanRemoval๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
๋„๋Œ€์ฒด OrphanRemoval๊ฐ€ ๋ญ˜๊นŒ?

 

 

 

1. ๊ณ ์•„ ๊ฐ์ฒด๋ž€?

  • ๋ถ€๋ชจ ๊ฐ์ฒด์™€ ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง„ ์ž์‹ ๊ฐ์ฒด๋ฅผ JPA์—์„œ ๊ณ ์•„๊ฐ์ฒด๋ผ๊ณ  ํ•œ๋‹ค.
  • ์•„๋ž˜์ฒ˜๋Ÿผ ์ฃผ๋ฌธ์ด ๋“ค์–ด์™”๋‹ค.
Order
 โ”œโ”€ OrderItem
 โ”œโ”€ OrderItem
 โ””โ”€ OrderItem
  • ๊ทธ๋Ÿฐ๋ฐ ์–ด๋А ์ˆœ๊ฐ„ ์ฃผ๋ฌธ์—์„œ ์ƒํ’ˆ ํ•˜๋‚˜๋ฅผ ์ œ๊ฑฐํ–ˆ๋‹ค.
order.getOrderItems().remove(item); // ์ œ๊ฑฐ
item.setOrder(null);
  • ๊ทธ๋Ÿฌ๋ฉด ์ด OrderItem์€ ๋” ์ด์ƒ ์–ด๋–ค Order์—๋„ ์†ํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.
Order
 โ”œโ”€ OrderItem
 โ””โ”€ OrderItem

OrderItem ← ๋ถ€๋ชจ๋ฅผ ์žƒ์—ˆ๋”ฐ

 

 

 

 


 

 

 

2. OrphanRemoval = true

  • OrphanRemoval = true๋Š” ๊ณ ์•„ ๊ฐ์ฒด๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ, JPA๊ฐ€ ์ž๋™์œผ๋กœ ์‚ญ์ œํ•ด์ฃผ๋Š” ์˜ต์…˜์ด๋‹ค.
  • ์ฆ‰, ๋ถ€๋ชจ ๊ฐ์ฒด๊ฐ€ ๋” ์ด์ƒ ์ž์‹ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋ฉด ๊ทธ ์ž์‹ ๊ฐ์ฒด๋Š” DB์—์„œ๋„ ์‚ญ์ œํ•˜๋ผ๋Š” ๊ฒƒ.
  • ๋ณดํ†ต ์•„๋ž˜์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> orderItems = new ArrayList<>();
  • ์ด๋ ‡๊ฒŒ ์„ค์ •ํ•˜๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋ถ€๋ชจ ์ปฌ๋ ‰์…˜์—์„œ ์ž์‹์„ ์ œ๊ฑฐํ–ˆ์„ ๋•Œ
order.getOrderItems().remove(orderItem);
  • JPA๊ฐ€ ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๋Š” ์‹œ์ ์— ์ด๋Ÿฐ SQL์„ ๋‚ ๋ฆด ์ˆ˜ ์žˆ๋‹ค.
DELETE FROM order_item WHERE id = ?
  • ์ž๋ฐ” ์ฝ”๋“œ์—์„œ๋Š” ๋‹จ์ˆœํžˆ ๋ฆฌ์ŠคํŠธ์—์„œ ๋บ์„ ๋ฟ์ธ๋ฐ, DB์—์„œ๋Š” ์‹ค์ œ๋กœ ์‚ญ์ œ๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.
  • ๋งŒ์•ฝ ์ด ๋‚ด์šฉ์ด ์ดํ•ด๊ฐ€ ์•ˆ๋œ๋‹ค๋ฉด ์•„๋ž˜ ๋‚ด์šฉ์„ ๋จผ์ € ์ฝ๊ณ  ์˜ค์ž.

 

 

- ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €

 

[Spring][JPA] ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €(EntityManager)์™€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์‰ฝ๊ฒŒ ์ดํ•ดํ•ด๋ณด์ž!

์ „ ํฌ์ŠคํŒ…์—์„œ Cascade์— ๋Œ€ํ•ด ์„ค๋ช…ํ–ˆ๋‹ค.์‚ฌ์‹ค Cascade๋ฅผ ๋” ์ž˜ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ์—”ํ‹ฐํ‹ฐ๋งค๋‹ˆ์ €๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ๊ณ  ์žˆ์œผ๋ฉด ์ข‹๋‹ค.๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—” ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋ฅผ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค. 1. ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €(Entit

post-this.tistory.com

 

 

- Cascade

 

[Spring][JPA] Cascade์˜ ์˜๋ฏธ์™€ ์ข…๋ฅ˜ ์•Œ์•„๋ณด๊ธฐ.

๋‹ค๋Œ€๋‹ค ๋งคํ•‘ ์—”ํ‹ฐํ‹ฐ ๊ตฌ์กฐ๋ฅผ ์„ค๊ณ„ํ•˜๋ฉด์„œCascade ํƒ€์ž…์„ ์„ค์ •ํ–ˆ๋‹ค.Cascade๊ฐ€ ๋ฌด์—‡์ด๋ฉฐ ์–ด๋–ค ์ข…๋ฅ˜๊ฐ€ ์žˆ๋Š”์ง€ ์‚ดํŽด๋ณด์ž. 1. Cascade์˜์†์„ฑ์€ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ๋‚˜ ๊ฐ์ฒด๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•˜๊ฑฐ๋‚˜ ์‹œ์Šคํ…œ์ด ์žฌ๋ถ€

post-this.tistory.com

 

 

 


 

 

 

 

3. CascadeType.REMOVE์™€ orphanRemoval์˜ ์ฐจ์ด

  • CascadeType.REMOVE๋Š” ๋ถ€๋ชจ ์ž์ฒด๊ฐ€ ์‚ญ์ œํ•  ๋•Œ ์ž์‹๋„ ๊ฐ™์ด ์‚ญ์ œ๋œ๋‹ค.
orderRepository.delete(order);
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Order๋„ ์‚ญ์ œ๋˜๊ณ  OrderItems๋“ค๋„ ํ•จ๊ป˜ ์‚ญ์ œ๋œ๋‹ค. => ๋ถ€๋ชจ๊ฐ€ ์ฃฝ์œผ๋ฉด ์ž์‹๋„ ๊ฐ™์ด ์‚ฌ๋ผ์ง€๋Š” ๊ตฌ์กฐ์ด๋‹ค.

 

 

  • orphanRemoval = true๋Š” ๋ถ€๋ชจ๊ฐ€ ์‚ด์•„์žˆ์–ด๋„ ๋ถ€๋ชจ์™€ ์ž์‹์˜ ๊ด€๊ณ„๊ฐ€ ๋Š๊ธฐ๋ฉด ์ž์‹์ด ์‚ญ์ œ๋œ๋‹ค.
order.getOrderItems().remove(orderItem);
Order๋Š” ๊ทธ๋Œ€๋กœ ์กด์žฌํ•˜๊ณ  ์ œ๊ฑฐ๋œ OrderItem๋งŒ ์‚ญ์ œ๋œ๋‹ค.  =>  ๋ถ€๋ชจ๊ฐ€ ์‚ด์•„์žˆ์–ด๋„ ๋ถ€๋ชจํ•œํ…Œ ๋ฒ„๋ ค์ง€๋ฉด ์ž์‹์€ ์‚ญ์ œ๋œ๋‹ค.

๋งŒ์•ฝ์— CascadeType.REMOVE๋Š” ์žˆ๊ณ  orphanRemoval = true๋Š” ์—†๋Š” ๊ฒฝ์šฐ ๋ถ€๋ชจํ•œํ…Œ ๋ฒ„๋ ค์ ธ๋„ ์ž์‹์€ ์‚ญ์ œ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— DB์—์„œ ์•„๋ฌด์ผ๋„ ๋ฒŒ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค. 

 

  • orphanRemoval = true๋Š” ์ž์‹์ด ๋ถ€๋ชจ ์—†์ด๋Š” ์˜๋ฏธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฒŒ์‹œ๊ธ€ ์†์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€์˜ ๊ฒฝ์šฐ ๊ฒŒ์‹œ๊ธ€์ด ์—†์ด๋Š” ์˜๋ฏธ๊ฐ€ ์—†๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ์‚ฌ์šฉ์— ์ ํ•ฉํ•˜๋‹ค.