Skip to content

Conversation

@whqtker
Copy link
Member

@whqtker whqtker commented Nov 20, 2025

관련 이슈

작업 내용

FK의 ON DELETE CASCADE 옵션을 사용하여 DB 레벨에서 연관 레코드를 삭제하도록 구현했습니다.
FK를 재설정하면서 컨벤션에 맞지 않았던 FK 제약조건 이름도 같이 수정했습니다.

특이 사항

UserRemovalScheduler 에 의하면 탈퇴 후 30일이 지나면 DB에서 Hard Delete가 이루어집니다.

public void scheduledUserRemoval() {
	LocalDate cutoffDate = LocalDate.now().minusDays(ACCOUNT_RECOVER_DURATION);
	List<SiteUser> usersToRemove = siteUserRepository.findUsersToBeRemoved(cutoffDate);
	siteUserRepository.deleteAll(usersToRemove);
}

이전에 불필요한 연관 관계를 끊고 간접 참조로 리팩터링을 진행한 바 있습니다. 이전에는 JPA의 cascade 옵션으로 연관 객체들 또한 잘 삭제되었으나, 연관 관계를 끊은 현재는 SiteUser 을 삭제하기 전, 연관 레코드를 먼저 삭제해야 합니다.

interestedCountryRepository.deleteAllBySiteUserIdIn(userIdsToRemove);

다만, SiteUser 와 간접적으로 관계를 맺는 객체가 정말 많기에, 위처럼 직접 연관된 레코드를 삭제하는 경우 코드가 길어지게 됩니다. SiteUser 를 참조하는 새로운 엔티티를 생성하는 경우 스케쥴러에서 삭제하는 로직 또한 작성해주어야 하는데, 실수할 여지가 있다고 생각했습니다.

리뷰 요구사항 (선택)

@whqtker whqtker self-assigned this Nov 20, 2025
@whqtker whqtker added the 버그 Something isn't working label Nov 20, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

🔄 Walkthrough

데이터베이스 마이그레이션 파일이 추가되었으며, 기존의 18개 외래 키 제약 조건에 ON DELETE CASCADE 옵션을 적용합니다. 각 제약 조건은 site_user 테이블 삭제 시 연쇄 삭제되도록 변경됩니다.

  1. interested_country, interested_region, comment, post 등 주요 테이블의 site_user_id 참조 제약 조건을 재생성
  2. mentoring의 mentee_id, report의 reporter_id, user_block의 blocker_id/blocked_id 등 다양한 사용자 참조 필드도 동일하게 업데이트
  3. 기존 외래 키를 삭제한 후 새로운 이름의 제약 조건으로 재생성 (예: fk_comment_site_user_id)

🎯 Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

  • 반복적인 패턴: 동일한 유형의 제약 조건 수정이 18개 테이블에 걸쳐 일관되게 적용되어 있습니다
  • 검증 포인트:
    • 마이그레이션 파일 SQL 문법 정확성 확인
    • 제약 조건명 오타 없음 여부 확인 (예: fk_app_site_user)
    • 모든 site_user 참조 FK가 포함되었는지 확인

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed PR 설명은 필수 섹션(관련 이슈, 작업 내용, 특이 사항)을 모두 포함하고 있으며, 변경 배경과 기술적 의도를 상세히 기술했습니다.
Linked Issues check ✅ Passed ON DELETE CASCADE 옵션 추가로 사용자 Hard Delete 문제를 DB 레벨에서 해결하며, #556의 연관 레코드 삭제 요구사항을 충족합니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 FK에 ON DELETE CASCADE를 추가하고 제약조건 이름을 규정화하는 범위 내에 있으며, #556의 사용자 Hard Delete 해결 목표와 일치합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed PR 제목이 변경사항의 핵심을 정확하게 반영하고 있습니다. 데이터베이스 FK에 ON DELETE CASCADE 옵션을 추가하는 주요 변경 사항을 명확하게 전달합니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@whqtker whqtker changed the title refactor: FK에 ON DELETE CASCADE 옵션 추가 refactor: 탈퇴한 사용자가 물리적 삭제가 되지 않았던 문제를 해결한다 Nov 20, 2025
@whqtker whqtker changed the title refactor: 탈퇴한 사용자가 물리적 삭제가 되지 않았던 문제를 해결한다 fix: 탈퇴한 사용자가 물리적 삭제가 되지 않았던 문제를 해결한다 Nov 20, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/main/resources/db/migration/V38__add_delete_cascade_option_on_fk.sql (3)

1-89: 마이그레이션 접근법은 명확하지만, 적용 범위와 롤백 전략 확인 필요합니다.

전반적으로 마이그레이션 구조는 건전합니다. site_user 테이블 삭제 시 관련 레코드를 연쇄적으로 삭제하는 방식으로 하드 딜리트 문제를 해결하는 것이 PR 목표와 일치합니다. 다음 몇 가지를 확인해 주세요:

  1. 외래 키 적용 범위 검증
    현재 마이그레이션이 site_user를 참조하는 모든 FK를 다루고 있는지 확인이 필요합니다. 마이그레이션 후 누락된 FK가 있으면 일부 연관 레코드가 여전히 삭제되지 않을 수 있습니다.

  2. 롤백 전략 부재
    역방향 마이그레이션(undo 스크립트)이 없으면 문제 발생 시 이전 상태로 복구하기 어렵습니다. Flyway는 일반적으로 단방향이지만, 이 구조적 변경에 대해 롤백 전략이 있는지 확인해 주세요.

  3. 프로덕션 배포 시 고려 사항
    DDL 작업은 영향을 받는 테이블을 잠금합니다. 특히 post, comment 같은 대형 테이블의 경우 마이그레이션 시간을 확인하고 적절한 점검 시간에 배포하세요.


1-89: 제약 조건 네이밍 컨벤션이 거의 일관성 있으나, 소수 불규칙성 정리 권장합니다.

대부분의 새 제약 조건 이름이 fk_[테이블]_[칼럼] 패턴을 따르고 있어 좋습니다. 단, 아래 두 가지 예외가 있습니다:

  1. Line 33-34 (fk_app_site_user): 테이블 약자와 칼럼명 생략 패턴으로 다른 네이밍과 톤이 다릅니다.
  2. Line 88-89 (fk_mentor_application_site_user): 다른 제약과 달리 _id 접미사가 없습니다.

장기 유지보수 관점에서 모든 FK 제약을 fk_[테이블]_[칼럼] 형식(예: fk_app_site_user_id, fk_mentor_application_site_user_id)으로 정렬하면 일관성이 높아집니다.


1-89: ON DELETE CASCADE 적용 시 의도하지 않은 연쇄 삭제 리스크를 모니터링하세요.

이 마이그레이션 후 site_user 레코드 삭제 시 위 18개 FK를 통해 관련된 모든 하위 레코드가 자동으로 삭제됩니다. 이는 의도된 동작이지만, 배포 후 몇 가지를 관찰해야 합니다:

  1. 의도하지 않은 데이터 손실 - 비즈니스 로직상 보존해야 할 데이터가 연쇄 삭제로 인해 손실되지 않는지 확인
  2. 애플리케이션 코드 정리 - PR 배경에 언급된 대로 UserRemovalScheduler의 연관 레코드 삭제 코드(siteUserRepository.deleteAll 전 개별 삭제 로직)가 이제 불필요할 가능성이 있으니 정리 검토 권장
  3. 데이터베이스 트리거/프로시저 - 기존에 수동으로 처리하던 삭제 로직이 있다면 중복 처리로 인한 오류를 피하도록 검토
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4da854b and 46df0f3.

📒 Files selected for processing (1)
  • src/main/resources/db/migration/V38__add_delete_cascade_option_on_fk.sql (1 hunks)
🔇 Additional comments (1)
src/main/resources/db/migration/V38__add_delete_cascade_option_on_fk.sql (1)

46-46: 일부 제약 조건에서 이미 같은 이름으로 존재하는 FK를 삭제 후 재생성하고 있습니다.

Line 46, 51, 56, 61, 71, 76, 81, 86에서 기존 제약 조건과 동일한 이름으로 FK를 재생성하고 있습니다. 이는 현재 스키마에서 이 제약들이 이미 사람이 정의한 이름으로 존재한다는 의미입니다.

확인 사항:

  • 이 제약 조건들이 정말로 같은 이름을 유지하는 것이 의도인지, 아니면 버전 관리 과정에서 일부는 이미 수정된 것인지 검증해 주세요.
  • 특히 application 테이블(Line 31)의 경우 이미 fk_app_site_user 이름으로 존재하는 것으로 보아, 이전 마이그레이션에서 수동으로 명명한 제약으로 추정됩니다.

Also applies to: 51-51, 56-56, 61-61, 71-71, 76-76, 81-81, 86-86

Copy link
Contributor

@Hexeong Hexeong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하십니다~ FK ID 관련하여 질문 있어서 comment 남겨뒀습니다~

@@ -0,0 +1,89 @@
ALTER TABLE interested_country DROP FOREIGN KEY FK26u5am55jefclcd7r5smk8ai7;
ALTER TABLE interested_country
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FK ID가 로컬에서와 인스턴스에서가 다를 것 같은데, 하드 코딩된 이유가 따로 있을까요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flyway가 stage, prod 환경에서만 동작하고, 확인한 결과 두 환경 모두 FK가 같아서 단순 하드 코딩했습니다

Copy link
Contributor

@sukangpunch sukangpunch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘 작성해주신 것 같습니다!!
근데 고민이 하나 있는데, 엔티티 클래스 에서 jpa 연관관계를 다 끊어 놓은 상황에서 db 에서 casecade 구현하는게 괜찮을까? 라는 생각이 들었습니다.
제가 까먹어서 그런데, 연관관계 매핑을 끊었던 이유를 혹시 알고 계신가요? 들었던것 같은데 기억이 안나네요...

@Gyuhyeok99
Copy link
Contributor

음 이러면 코드와 디비간의 불일치가 발생할 거 같긴한데 문제는 없어보이네요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

버그 Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: 사용자 Hard Delete가 안 되는 문제를 해결한다.

4 participants