๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป ํ”„๋กœ์ ํŠธ/๐Ÿ‘‘ VIP ์ดˆ๋Œ€์žฅ ๐Ÿ’Œ

[Spring, React] flush( )๋ฅผ ์‚ฌ์šฉํ•ด์„œ DB ์˜ค๋ฅ˜ ํ•ด๊ฒฐํ•˜๊ธฐ

by hyeong._.ing 2026. 6. 2.

 

 

๊ด€๋ฆฌ์ž ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ–ˆ๋”๋‹ˆ
์ค‘๋ณต ์ €์žฅ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.
์—๋Ÿฌ์˜ ์›์ธ์„ ์ฐพ๊ณ  ์ˆ˜์ •ํ•ด๋ณด์ž.

 

 

 

 

1. ์—๋Ÿฌ

Duplicate entry '2-3' for key 'admin_permission.uk_admin_permission'
์ฒ˜์Œ ๋กœ์ง์€ ์ด๋žฌ๋‹ค. [ ๊ด€๋ฆฌ์ž ์ •๋ณด ์ˆ˜์ • ] - [ ๊ธฐ์กด ๊ถŒํ•œ ์‚ญ์ œ ] - [์ƒˆ ๊ถŒํ•œ ๋‹ค์‹œ ์ €์žฅ] ํ๋ฆ„์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ƒ๊ฐํ•œ ํ๋ฆ„๋Œ€๋กœ ์ผ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š์€ ๋ชจ์–‘์ด๋‹ค. ์–ด๋””์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ DB๋ถ€ํ„ฐ ๋‹ค์‹œ ์‚ดํŽด๋ดค๋‹ค.
AdminService์˜ update ์ฝ”๋“œ ์ค‘ ์ผ๋ถ€

// ๊ธฐ์กด ๊ถŒํ•œ ์‚ญ์ œ
adminPermissionRepository.deleteByAdminId(id);
// ๋‹ค์‹œ ์ €์žฅ
savePermissions(id, request.getPermissions());โ€‹

 

DB๋ฅผ 3๊ฐœ๋กœ ๋ถ„๋ฆฌํ•ด๋’€๋‹ค. ๊ด€๋ฆฌ์ž์˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” Admin, ๊ถŒํ•œ ์ข…๋ฅ˜๋ฅผ ์ €์žฅํ•˜๋Š” Permission, ๊ด€๋ฆฌ์ž์™€ ๊ถŒํ•œ์„ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”์ธ AdminPermission. ๊ทธ๋ฆฌ๊ณ  admin_permission ํ…Œ์ด๋ธ”์—๋Š” ์œ ๋‹ˆํฌ ์ œ์•ฝ์„ ๊ฑธ์–ด์„œ ๊ด€๋ฆฌ์ž์™€ ๊ถŒํ•œ์˜ ์กฐํ•ฉ์ด ์ค‘๋ณต๋  ์ˆ˜ ์—†๋„๋ก ์„ค์ •ํ–ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ Duplicate entry '2-3'์€ admin_id = 2์™€ permission_id = 3์˜ ์กฐํ•ฉ์ด ์ค‘๋ณต๋˜์—ˆ๋‹ค๊ณ  ์•Œ๋ ค์ค€ ๊ฒƒ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด์„œ 2๋ฒˆ ๊ด€๋ฆฌ์ž๊ฐ€ 3๋ฒˆ ๊ถŒํ•œ์ธ ADD ๊ถŒํ•œ์„ ๊ฐ–๊ณ  ์žˆ๋Š”๋ฐ, ์ด 2-3 ์กฐํ•ฉ์„ ๋‹ค์‹œ ํ•œ ๋ฒˆ insertํ•˜๋ ค๊ณ  ํ–ˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ๋‹ค. ์ด๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ•œ ์ด์œ ๋Š” ์•„๋งˆ๋„ ๊ธฐ์กด ๊ถŒํ•œ ์‚ญ์ œ๊ฐ€ ์ œ๋Œ€๋กœ ์ด๋ค„์ง€์ง€ ์•Š์€๊ฒŒ ์•„๋‹๊นŒ๋ผ๊ณ  ์ถ”์ธกํ–ˆ๋‹ค. 

 

 

 

 


 

 

 

 

2. flush( )

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ(Persistence Context)์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋™๊ธฐํ™”ํ•˜๋Š” ์ž‘์—…์„ ๋งํ•œ๋‹ค.
  • ์‰ฝ๊ฒŒ ๋งํ•ด์„œ, ๋ฉ”๋ชจ๋ฆฌ์ƒ์—์„œ ๋ณ€๊ฒฝ๋œ ๋ฐ์ดํ„ฐ๋“ค์„ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ฟผ๋ฆฌ(SQL)๋กœ ๋‚ ๋ ค ์ƒํƒœ๋ฅผ ๋˜‘๊ฐ™์ด ๋งž์ถ”๋Š” ๊ณผ์ •์ด๋‹ค.
  • JPA๋Š” ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์ฟผ๋ฆฌ๋ฅผ ๋ฐ”๋กœ ๋‚ ๋ฆฌ์ง€ ์•Š๊ณ  ์“ฐ๊ธฐ ์ง€์—ฐ์ด๋ž€ ๊ฐœ๋…์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • flush( )๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์“ฐ๊ธฐ ์ง€์—ฐ ๋•Œ๋ฌธ์— ๋ฐ€๋ ค์žˆ๋˜ INSERT, UPDATE ๋“ฑ ์ฟผ๋ฆฌ๋“ค์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ๋‚ ์•„๊ฐ„๋‹ค.

 

Q. flush( )๋Š” ์–ธ์ œ ๋ฐœ์ƒํ•˜๋Š”๊ฐ€?

A. ์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด JPA๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ตœ์†Œํ™”ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์“ฐ๊ธฐ ์ง€์—ฐ์ด๋ผ๋Š” ๊ฐœ๋…์„ ์‚ฌ์šฉํ•œ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •, ์‚ญ์ œํ•ด๋„ ์ฆ‰์‹œ DB์— ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. ๋Œ€์‹  ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๋‚ด๋ถ€์˜ ์“ฐ๊ธฐ ์ง€์—ฐ SQL ์ €์žฅ์†Œ์— ์ฟผ๋ฆฌ(INSERT, UPDATE, DELETE)๋ฅผ ์ฐจ๊ณก์ฐจ๊ณก ๋ชจ์•„ ๋‘”๋‹ค. ์ด ๋ชจ์•„๋‘” ์ฟผ๋ฆฌ๋ฅผ ํ•œ ๋ฒˆ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์Ÿ์•„๋‚ด๋Š” ์ž‘์—…์ด ๋ฐ”๋กœ flush( )์ด๋‹ค.

flush( )๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„ ํ”„๋ ˆ์ž„์›Œํฌ์— ์˜ํ•ด ์ž๋™์œผ๋กœ ๋ฐœ์ƒํ•œ๋‹ค. @Transcational ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋๋‚˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ปค๋ฐ‹์„ ํ•˜๊ธฐ ์ง์ „์— ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋œ๋‹ค. JPQL์ด๋‚˜ QueryDSL ๋“ฑ์„ ํ†ตํ•ด DB์— ์ง์ ‘ ์กฐํšŒ ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฌ๊ธฐ ์ง์ „์— ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋œ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ์—๋งŒ ์žˆ๊ณ  DB์—๋Š” ๋ฐ˜์˜๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ ๋•Œ๋ฌธ์— ์ž˜๋ชป๋œ ๊ฒฐ๊ณผ๊ฐ€ ์กฐํšŒ๋˜๋Š” ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค. ์ง์ ‘ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ๋Š”, repository.flush( ) ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

 

 

 


 

 

 

 

3. ์—๋Ÿฌ ๊ณ ์น˜๊ธฐ 

  • AdminService
// ๊ธฐ์กด ๊ถŒํ•œ ์‚ญ์ œ
adminPermissionRepository.deleteByAdminId(id);
// ์‚ญ์ œ ๋‚ด์šฉ์„ DB์— ๋ฐ˜์˜
adminPermissionRepository.flush();
// ์ƒˆ ๊ถŒํ•œ ๋‹ค์‹œ ์ €์žฅ
savePermissions(id, request.getPermissions());

 

๊ธฐ์กด ๊ถŒํ•œ์„ ์‚ญ์ œ๋ฅผ ํ•˜๊ณ  ๋‚˜๋ฉด flush( )๋กœ ์‚ญ์ œ SQL์„ ๊ฐ•์ œ๋กœ ๋จผ์ € ์‹คํ–‰์‹œ์ผœ์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๊ฑธ ๋ง‰๋„๋ก ํ–ˆ๋‹ค.

 

 

Q. ์ด ์ฝ”๋“œ๋Š” ๊ฝค ๊ดœ์ฐฎ์€ ์ฝ”๋“œ์ผ๊นŒ?

A. flush( )๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์˜ค๋ฅ˜๋ฅผ ์ผ์‹œ์ ์œผ๋กœ ๊ณ ์น˜๊ธด ํ–ˆ์ง€๋งŒ, ์ด ์ฝ”๋“œ๊ฐ€ ๊ฝค ๊ดœ์ฐฎ์€๊ฑด์ง€์— ๋Œ€ํ•ด์„œ๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค. ์ด ์ฝ”๋“œ๋Š” ํ…Œ์ด๋ธ” ์ค‘์‹ฌ ์ฝ”๋“œ์ด๋‹ค. ์ง์ ‘ ํ…Œ์ด๋ธ”์„ ๊ฑด๋“œ๋ฆฐ๋‹ค๋Š” ๋ง์ด๋‹ค. admin_permission ํ…Œ์ด๋ธ”์˜ admin_id, permission_id ํ–‰์„ ์ง์ ‘ ์‚ญ์ œ/์‚ฝ์ž…ํ•˜๊ณ  ์žˆ๋‹ค. ์ด๊ฑด SQL ํ…Œ์ด๋ธ”์„ ์ˆ˜๋™์œผ๋กœ ๋‹ค๋ฃจ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

์ฒ˜์Œ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์„๋•Œ, [ ๊ด€๋ฆฌ์ž ์ •๋ณด ์ˆ˜์ • ] - [ ๊ธฐ์กด ๊ถŒํ•œ ์‚ญ์ œ ] - [ ์ƒˆ ๊ถŒํ•œ ๋‹ค์‹œ ์ €์žฅ ]์ด ์ €์ ˆ๋กœ ๋ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์•„๋‹ˆ์—ˆ๋‹ค. ๋˜  flush( )๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ์ด ๋˜์–ด์•ผํ•œ๋‹ค. ๊ทธ๋Ÿผ ์™œ ์•ˆ๋œ๊ฑด์ง€์— ๋Œ€ํ•ด์„œ ์ƒ๊ฐํ•ด๋ด์•ผํ•˜๋Š”๋ฐ, ๊ทธ ์ด์œ ๊ฐ€ ํ…Œ์ด๋ธ”์„ ์ง์ ‘์ ์œผ๋กœ ๊ฑด๋“œ๋ฆฌ๊ณ  ์™ธ๋ž˜ํ‚ค ID๋ฅผ ์ง์ ‘ ๋„ฃ๋Š” ๊ฒƒ์ด ๋ฌธ์ œ์ธ๊ฒŒ ์•„๋‹Œ์ง€ ์ถ”์ธกํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค. 
// ์™ธ๋ž˜ํ‚ค๋ฅผ ์ง์ ‘ ๋„ฃ์€ ์ฝ”๋“œ

adminPermission.setAdminId(adminId);
adminPermission.setPermissionId(permission.getId());


JPA๋Š” ์›๋ž˜ ํ…Œ์ด๋ธ” ํ–‰์„ ์ง์ ‘ ์กฐ์ž‘ํ•˜๊ธฐ๋ณด๋‹ค ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด์˜ ์ƒํƒœ์™€ ๊ด€๊ณ„๋ฅผ ๋ฐ”๊พธ๋ฉด Hibernate๊ฐ€ SQL๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ๊ตฌ์กฐ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์ง€๊ธˆ ์ฝ”๋“œ๋Š” JPA๋ฅผ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•œ๋‹ค๊ณ  ๋ด์•ผํ•œ๋‹ค. 

// ์—”ํ‹ฐํ‹ฐ ๊ด€๊ณ„๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•œ ์ฝ”๋“œ

adminPermission.setAdmin(admin);
adminPermission.setPermission(permission);


์œ„์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋ฐ”๊พผ๋‹ค๋ฉด ๊ฐ์ฒด ๊ด€๊ณ„๊ฐ€ ์ฝ”๋“œ์ƒ์—์„œ ๋“ค์–ด๋‚˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ํ…Œ์ด๋ธ” ์ค‘์‹ฌ ์ฝ”๋“œ์—์„œ ๊ฐ์ฒด ๊ด€๊ณ„ ์ค‘์‹ฌ ์ฝ”๋“œ๋กœ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค. ๋ฌผ๋ก  ์œ„์˜ ์ฝ”๋“œ๋กœ ๋ฐ”๊พธ๋ ค๋ฉด ์ „๋ฐ˜์ ์ธ ์ˆ˜์ •์ด ํ•„์š”ํ•  ๊ฒƒ์ด๋‹ค.