cascade.REMOVE ์—๋Ÿฌ(feat. ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ, @Query)

์šฐ์„  ๋ถ€๋ชจ์—”ํ‹ฐํ‹ฐ์™€ ์ž์‹ ์—”ํ‹ฐํ‹ฐ์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

 

Ticketing ๊ณผ SelectedSeat์€ 1:N ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘์ด ๋งบ์–ด์ ธ์žˆ๋‹ค. 

cascade.REMOVE ์˜ต์…˜์„ ๊ฑธ์–ด ํ‹ฐ์ผ“ ์˜ˆ๋งค๋ฅผ ์ทจ์†Œํ•  ๊ฒฝ์šฐ SelectedSeat๋„ ์‚ญ์ œํ•  ์ƒ๊ฐ์ด์—ˆ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

 

 

ํ•˜์ง€๋งŒ selectedSeat์˜ ์ฐธ์กฐ ์—๋Ÿฌ๊ฐ€ ํ„ฐ์กŒ๋‹ค.

Cannot delete or update a parent row: a foreign key constraint fails (`tickerBellDB`.`selected_seat`, CONSTRAINT `FKsfrjmwj259n0yrhm0f0idjnrc` FOREIGN KEY (`ticketing_id`) REFERENCES `ticketing` (`ticketing_id`))

 

์ฟผ๋ฆฌ๋ฅผ ์‚ดํŽด๋ณด๋‹ˆ SelectedSeat์˜ delete ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ticketing delete ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ”๋‹ค.

 

 

 

 

์ด๊ฒƒ์ €๊ฒƒ ํ•ด๋ณด๋‹ค๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•„ ๋ช…์‹œ์ ์œผ๋กœ SelectedSeat์— ๋Œ€ํ•œ delete ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ ค๋ณด์•˜๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋ž˜๋„ delete ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€์ง€ ์•Š์•˜๋‹ค. 

 

orphanRemove๋„ ๋ถ™์—ฌ๋ณด๊ณ  ์ด๊ฒƒ์ €๊ฒƒ ๋ง‰ ์‹œ๋„ํ•˜๋‹ค ticketing์ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์˜ฌ๋ผ๊ฐ€์žˆ๋Š”๋ฐ selectedSeat๊ณผ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ๋งบ์–ด์ ธ์žˆ๋Š” ์ƒํƒœ๋ผ SelectedSeat delete ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€์ง€ ์•Š๋Š”๊ฑธ๊นŒ? ํ•˜๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์˜ฌ๋ผ๊ฐ€์žˆ๋Š” ticketing์—์„œ SelectedSeat๊ณผ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ๋Š์–ด๋ณด์•˜๋‹ค. 

ticketing.setSelectedSeatList(null);

 

์ด๋ ‡๊ฒŒ ํ•˜๋‹ˆ delete ์ฟผ๋ฆฌ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ž˜ ๋‚˜๊ฐ”๋‹ค. 

 

 

๋‚˜์˜ ์ƒ๊ฐ์ด ๋งž์•˜๋‚˜..? ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์˜ฌ๋ผ๊ฐ€์žˆ๋Š” Ticketing์€ SelectedSeat๊ณผ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”๋ฐ, SelectedSeat์„ ์‚ญ์ œํ•˜๋ คํ•˜๋‹ˆ ์ฟผ๋ฆฌ๊ฐ€ ์ œ๋Œ€๋กœ ๋‚˜๊ฐ€์ง€ ์•Š์•˜๋˜ ๊ฒƒ์ด๋‹ค. 

 

 

์—ฌ๊ธฐ๊นŒ์ง„ ์ดํ•ด๊ฐ€ ๋๋Š”๋ฐ ๊ทธ๋ ‡๋‹ค๋ฉด cascade.REMOVE ์˜ต์…˜์€ ์‚ฌ์šฉํ•˜์ง€ ๋ชป ํ•˜๋Š”๊ฑด๊ฐ€? ์— ๋Œ€ํ•œ ์˜๋ฌธ์ด ํ’€๋ฆฌ์ง€ ์•Š์•˜๋‹ค.

 

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋ช…์‹œ์ ์œผ๋กœ ์‚ญ์ œํ•  ๋•Œ ํ–ˆ๋˜ ๊ฒƒ ์ฒ˜๋Ÿผ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ null๋กœ ํ•ด์ฃผ๊ณ  ticketing ์„ ์‚ญ์ œํ•ด ๋ณด์•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ์—๋Ÿฌ๊ฐ€ ๋–ด๋‹ค.

 

 

์‚ฝ์งˆ ๋์— ๋‹ต์„ ์ฐพ์•˜๋‹ค.

 

๋ฌธ์ œ์˜ ์›์ธ์ด ๋๋˜ ๋ถ€๋ถ„์€ deleteByMemberAndTicketing ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ์ด์—ˆ๋‹ค. deleteByMemberAndTicketing์˜ ๊ตฌํ˜„ ๋‚ด์šฉ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. @Modifying๊ณผ @Query๋ฅผ ์‚ฌ์šฉํ•œ๊ฒŒ ์›์ธ์ด์—ˆ๋‹ค.

 

 

@Modifying, @Query

@Modifying

  • @Query ์–ด๋…ธํ…Œ์ด์…˜(JPQL Query, Native Query)์„ ํ†ตํ•ด ์ž‘์„ฑ๋œ INSERT, UPDATE, DELETE(SELECT ์ œ์™ธ) ์ฟผ๋ฆฌ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜

@Query

  • @Query๋กœ ์ •์˜๋œ ๋ฒŒํฌ ์—ฐ์‚ฐ JPQL์€ ๊ธฐ์กด JPA์ฒ˜๋Ÿผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๊ฑฐ์ณ ์“ฐ๊ธฐ์ง€์—ฐSQL๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋ฐ”๋กœ Database์— ์งˆ์˜๋ฅผ ํ•จ.

๋ณดํ†ต JPA๋Š” ์“ฐ๊ธฐ์ง€์—ฐ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๋Š” ํƒ€์ด๋ฐ, ์ฆ‰ ๋ฉ”์†Œ๋“œ๊ฐ€ ๋๋‚  ๋•Œ ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ, ์•„๋ž˜ ์ฝ”๋“œ์—์„  "1" , "2" ๊ฐ€ ์ฐํžˆ๊ณ  ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€์ง€๋งŒ @Query๋ฅผ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— "1" ์ด ๋จผ์ € ์ฐํžˆ๊ณ  ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ์„ ์˜ˆ์ƒํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

 

๋กœ๊ทธ ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

 

 

์ •๋ฆฌํ•ด๋ณด๋ฉด..

JPA์˜ cascade ์˜ต์…˜์€ DB์™€๋Š” ๋ณ„๊ฐœ์ด๋‹ค. (DDL์„ ํ™•์ธํ•ด๋ดค์„ ๋•Œ ๋”ฐ๋กœ ์ œ์•ฝ์กฐ๊ฑด์ด ์กด์žฌํ•˜์ง€ ์•Š์•˜์Œ)

๋”ฐ๋ผ์„œ JPA cascade์˜ต์…˜์„ ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ์‚ญ์ œ ์ž‘์—…์ด ์ด๋ค„์ ธ์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค. ์ฆ‰ em.remove()๋กœ ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ œ๊ฑฐ๋˜์•ผ ์ž์‹ ์—”ํ‹ฐํ‹ฐ๋„ cascade ์˜ต์…˜์œผ๋กœ ์ œ๊ฑฐ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. 

ํ•˜์ง€๋งŒ @Query ์–ด๋…ธํ…Œ์ด์…˜ ๊ฐ™์€ ๊ฒฝ์šฐ ์“ฐ๊ธฐ์ง€์—ฐSQL๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋ฐ”๋กœ Database์— ์งˆ์˜๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— DB์—์„œ ๋ฐ”๋กœ ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ œ๊ฑฐํ•ด๋ฒ„๋ ธ๊ณ  ๊ทธ ์ฆ‰์‹œ ์ž์‹ ์—”ํ‹ฐํ‹ฐ์—์„œ ์ฐธ์กฐ ์—๋Ÿฌ๊ฐ€ ํ„ฐ์ง„ ๊ฒƒ์ด์—ˆ๋‹ค. 

 

@Query ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ญ์ œ ๋กœ์ง ๋ง๊ณ  JPA์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” delete() ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์‚ญ์ œํ•˜์—ฌ ํ•ด๋‹น ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.