Skip to content

fix: provider_id가 null인 컬럼에 대해서도 데이터 이관 처리#362

Merged
dh2906 merged 2 commits intodevelopfrom
fix/v43-data-migration
Mar 9, 2026
Merged

fix: provider_id가 null인 컬럼에 대해서도 데이터 이관 처리#362
dh2906 merged 2 commits intodevelopfrom
fix/v43-data-migration

Conversation

@dh2906
Copy link
Contributor

@dh2906 dh2906 commented Mar 9, 2026

🔍 개요

  • close #이슈번호

🚀 주요 변경 내용


💬 참고 사항


✅ Checklist (완료 조건)

  • 코드 스타일 가이드 준수
  • 테스트 코드 포함됨
  • Reviewers / Assignees / Labels 지정 완료
  • 보안 및 민감 정보 검증 (API 키, 환경 변수, 개인정보 등)

@dh2906 dh2906 self-assigned this Mar 9, 2026
@dh2906 dh2906 added the DB DB 마이그레이션을 위한 라벨입니다. label Mar 9, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

📝 Walkthrough

Walkthrough

user_oauth_account 테이블 마이그레이션에서 provider_id를 NOT NULL에서 nullable로 변경하고, INSERT/NOT EXISTS 로직에서 NULL 가능성을 고려하도록 필터 및 비교식을 수정했습니다.

Changes

Cohort / File(s) Summary
데이터베이스 마이그레이션
src/main/resources/db/migration/V43__add_user_oauth_account_table.sql
provider_id 컬럼 제약을 NOT NULL → nullable로 변경. INSERT ... SELECT의 AND u.provider_id IS NOT NULL 필터 제거. NOT EXISTS 비교에서 NULL-safe 비교식으로 대체하여 NULLprovider_id도 삽입 대상 및 존재 검사에 포함되도록 변경.

Sequence Diagram(s)

(생성 조건 미충족 — 생략)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10분

Possibly related PRs

Suggested labels

버그

Poem

🐰
provider_id여, 이젠 가벼워져라,
NULL의 들판에 부드럽게 내려앉고,
레코드는 하나 더 늘어나며 웃네,
마이그레이션 소식에 당근 한 입,
폴짝폴짝, 데이터베이스 축제🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive PR 설명이 표준 템플릿 형식만 포함되어 있고 실질적인 구현 세부 사항이나 변경 내용에 대한 설명이 비어있습니다. 개요, 주요 변경 내용, 참고 사항 섹션을 채워서 변경 사유, 영향 범위, 추가 정보 등을 명시적으로 설명해주세요.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경 사항의 주요 내용을 정확히 설명하고 있습니다. provider_id가 NULL인 컬럼에 대한 데이터 이관 처리라는 구체적인 변경 목적을 명확하게 전달합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/v43-data-migration

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.

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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/resources/db/migration/V43__add_user_oauth_account_table.sql (2)

30-35: ⚠️ Potential issue | 🔴 Critical

[LEVEL: Critical] NULL 비교 로직 오류로 중복 삽입 또는 제약조건 위반 가능

ua.provider_id = u.provider_id 조건은 provider_id가 NULL인 경우 정상 동작하지 않습니다. SQL에서 NULL = NULL은 NULL을 반환하며 TRUE가 아니므로, NOT EXISTS 절이 기존 NULL provider_id 행을 감지하지 못합니다.

결과적으로:

  • 동일한 (provider, NULL) 조합이 이미 존재해도 중복 삽입 시도
  • UNIQUE 제약조건 위반 또는 의도치 않은 중복 데이터 발생 가능
🐛 NULL-safe 비교를 위한 수정 제안
  AND NOT EXISTS (
    SELECT 1
    FROM user_oauth_account ua
    WHERE ua.provider = u.provider
-      AND ua.provider_id = u.provider_id
+      AND (ua.provider_id = u.provider_id OR (ua.provider_id IS NULL AND u.provider_id IS NULL))
  );

또는 MySQL의 NULL-safe 비교 연산자 사용:

  AND NOT EXISTS (
    SELECT 1
    FROM user_oauth_account ua
    WHERE ua.provider = u.provider
-      AND ua.provider_id = u.provider_id
+      AND ua.provider_id <=> u.provider_id
  );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/db/migration/V43__add_user_oauth_account_table.sql` around
lines 30 - 35, The NOT EXISTS check currently uses "ua.provider_id =
u.provider_id" which fails for NULLs; update the NULL comparison to a NULL-safe
form so existing rows with provider_id IS NULL are detected—for Postgres replace
"ua.provider_id = u.provider_id" with "ua.provider_id IS NOT DISTINCT FROM
u.provider_id" (or for MySQL use the NULL-safe operator "ua.provider_id <=>
u.provider_id"); keep the rest of the NOT EXISTS clause and aliases
(user_oauth_account as ua and the source alias u) unchanged.

13-14: ⚠️ Potential issue | 🟠 Major

[LEVEL: Major] UNIQUE 제약조건에 nullable 컬럼 포함 확인

UNIQUE (provider, provider_id) 제약조건에서 provider_id 컬럼이 NULL을 허용합니다(line 5: VARCHAR(255) NULL). MySQL에서는 UNIQUE 인덱스 내 NULL 값이 서로 다른 것으로 취급되어, 동일한 provider에 여러 개의 NULL provider_id 행이 허용됩니다.

현재 설계에서 이것이 의도된 동작인지 확인이 필요합니다. 만약 provider별로 NULL provider_id를 정확히 하나만 허용해야 한다면 다음 중 조치가 필요합니다:

  • provider_id를 NOT NULL로 변경
  • 제약조건 정의 또는 데이터 검증 로직 수정
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/db/migration/V43__add_user_oauth_account_table.sql` around
lines 13 - 14, The UNIQUE constraint uq_user_oauth_account_provider_provider_id
currently includes provider_id which is defined as nullable, causing MySQL to
allow multiple rows with the same provider and NULL provider_id; to fix, decide
intended behavior and either alter the column provider_id to NOT NULL or change
the uniqueness strategy (e.g., remove provider_id from
uq_user_oauth_account_provider_provider_id and add a different constraint or
implement application-level validation) and update the migration
V43__add_user_oauth_account_table.sql accordingly to reflect the chosen
approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/resources/db/migration/V43__add_user_oauth_account_table.sql`:
- Line 5: The NOT EXISTS check in V43__add_user_oauth_account_table.sql
incorrectly compares ua.provider_id = u.provider_id which fails when
u.provider_id IS NULL, allowing duplicate rows; update the WHERE clause used in
the INSERT ... SELECT NOT EXISTS subquery (the condition referencing
ua.provider, ua.provider_id, u.provider and u.provider_id) to treat NULLs as
equal by replacing the simple equality with a compound check: (u.provider_id IS
NULL AND ua.provider_id IS NULL) OR ua.provider_id = u.provider_id so NULL
provider_id values are considered matching.

---

Outside diff comments:
In `@src/main/resources/db/migration/V43__add_user_oauth_account_table.sql`:
- Around line 30-35: The NOT EXISTS check currently uses "ua.provider_id =
u.provider_id" which fails for NULLs; update the NULL comparison to a NULL-safe
form so existing rows with provider_id IS NULL are detected—for Postgres replace
"ua.provider_id = u.provider_id" with "ua.provider_id IS NOT DISTINCT FROM
u.provider_id" (or for MySQL use the NULL-safe operator "ua.provider_id <=>
u.provider_id"); keep the rest of the NOT EXISTS clause and aliases
(user_oauth_account as ua and the source alias u) unchanged.
- Around line 13-14: The UNIQUE constraint
uq_user_oauth_account_provider_provider_id currently includes provider_id which
is defined as nullable, causing MySQL to allow multiple rows with the same
provider and NULL provider_id; to fix, decide intended behavior and either alter
the column provider_id to NOT NULL or change the uniqueness strategy (e.g.,
remove provider_id from uq_user_oauth_account_provider_provider_id and add a
different constraint or implement application-level validation) and update the
migration V43__add_user_oauth_account_table.sql accordingly to reflect the
chosen approach.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 46d53daf-4335-4a0f-994d-6cbcfc951ed1

📥 Commits

Reviewing files that changed from the base of the PR and between 077eb89 and e9709b4.

📒 Files selected for processing (1)
  • src/main/resources/db/migration/V43__add_user_oauth_account_table.sql
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
src/main/resources/db/migration/**/*.sql

⚙️ CodeRabbit configuration file

src/main/resources/db/migration/**/*.sql: Flyway 마이그레이션 리뷰 규칙:

  • 버전 파일명 규칙(V{number}__{description}.sql) 위반 여부를 우선 확인한다.
  • 이미 배포된 마이그레이션 수정/재번호 부여 위험이 있으면 반드시 차단 코멘트를 남긴다.
  • 파괴적 변경(drop, rename 등)은 롤백 가능성과 운영 영향 관점에서 검토한다.

Files:

  • src/main/resources/db/migration/V43__add_user_oauth_account_table.sql
**/*

⚙️ CodeRabbit configuration file

**/*: 공통 리뷰 톤 가이드:

  • 모든 코멘트는 첫 줄에 [LEVEL: ...] 태그를 포함한다.
  • 과장된 표현 없이 사실 기반으로 작성한다.
  • 한 코멘트에는 하나의 이슈만 다룬다.
  • 코드 예시가 필요하면 최소 수정 예시를 제시한다.
  • 가독성/단순화/확장성 이슈를 발견하면 우선순위를 높여 코멘트한다.

Files:

  • src/main/resources/db/migration/V43__add_user_oauth_account_table.sql

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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/resources/db/migration/V43__add_user_oauth_account_table.sql`:
- Around line 27-29: The WHERE clause in the migration now includes users with
provider IS NOT NULL but allows provider_id IS NULL; before running
V43__add_user_oauth_account_table.sql, verify the number of rows with deleted_at
IS NULL, provider IS NOT NULL and provider_id IS NULL in the users table to
ensure this change is intentional and results match expectations, and confirm
the NOT EXISTS clause that references provider and provider_id uses a NULL-safe
comparison to avoid mismatches when provider_id is NULL.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ffed152d-f92a-421f-8f08-80b6864e21dd

📥 Commits

Reviewing files that changed from the base of the PR and between e9709b4 and 9daf4c4.

📒 Files selected for processing (1)
  • src/main/resources/db/migration/V43__add_user_oauth_account_table.sql
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
src/main/resources/db/migration/**/*.sql

⚙️ CodeRabbit configuration file

src/main/resources/db/migration/**/*.sql: Flyway 마이그레이션 리뷰 규칙:

  • 버전 파일명 규칙(V{number}__{description}.sql) 위반 여부를 우선 확인한다.
  • 이미 배포된 마이그레이션 수정/재번호 부여 위험이 있으면 반드시 차단 코멘트를 남긴다.
  • 파괴적 변경(drop, rename 등)은 롤백 가능성과 운영 영향 관점에서 검토한다.

Files:

  • src/main/resources/db/migration/V43__add_user_oauth_account_table.sql
**/*

⚙️ CodeRabbit configuration file

**/*: 공통 리뷰 톤 가이드:

  • 모든 코멘트는 첫 줄에 [LEVEL: ...] 태그를 포함한다.
  • 과장된 표현 없이 사실 기반으로 작성한다.
  • 한 코멘트에는 하나의 이슈만 다룬다.
  • 코드 예시가 필요하면 최소 수정 예시를 제시한다.
  • 가독성/단순화/확장성 이슈를 발견하면 우선순위를 높여 코멘트한다.

Files:

  • src/main/resources/db/migration/V43__add_user_oauth_account_table.sql
🔇 Additional comments (2)
src/main/resources/db/migration/V43__add_user_oauth_account_table.sql (2)

34-37: [LEVEL: Approve] NULL 비교 로직이 올바르게 수정됨

SQL에서 NULL = NULL은 false를 반환하는 문제를 올바르게 처리했습니다. 수정된 패턴:

(u.provider_id IS NULL AND ua.provider_id IS NULL)
    OR ua.provider_id = u.provider_id

이 로직은 NULL provider_id를 가진 행들도 NOT EXISTS 검사에서 정확히 매칭되어 중복 삽입을 방지합니다.


5-5: [LEVEL: Resolve] NULL provider_id 설계는 적절하게 구현됨

provider_id가 nullable인 설계는 의도적이며 안전하게 구현되어 있습니다.

서비스 레이어에서 StringUtils.hasText(providerId) 가드(99, 108줄)로 NULL 값을 명시적으로 처리하며, provider_id가 없을 때는 email 기반 매칭으로 대체합니다(111-113줄). 핵심 lookup은 findByUserIdAndProvider()를 사용(115줄)하므로 provider_id의 NULL 여부와 무관하게 동작합니다.

(user_id, provider) 제약조건이 사용자당 provider별로 1개 계정만 허용하므로 데이터 중복도 방지됩니다. 마이그레이션의 NULL 안전 비교(34-37줄)도 올바릅니다.

Comment on lines 27 to 29
FROM users u
WHERE u.deleted_at IS NULL
AND u.provider IS NOT NULL
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

[LEVEL: Info] WHERE 조건 변경 확인

u.provider_id IS NOT NULL 필터가 제거되어 NULL provider_id를 가진 사용자도 마이그레이션 대상에 포함됩니다. 이는 의도된 변경으로 보이며, NOT EXISTS 절의 NULL-safe 비교와 함께 올바르게 작동합니다.

다만, 마이그레이션 실행 전 NULL provider_id를 가진 행의 수를 확인하여 예상 결과와 일치하는지 검증하는 것을 권장합니다:

-- 실행 전 확인용 쿼리
SELECT COUNT(*) FROM users WHERE deleted_at IS NULL AND provider IS NOT NULL AND provider_id IS NULL;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/db/migration/V43__add_user_oauth_account_table.sql` around
lines 27 - 29, The WHERE clause in the migration now includes users with
provider IS NOT NULL but allows provider_id IS NULL; before running
V43__add_user_oauth_account_table.sql, verify the number of rows with deleted_at
IS NULL, provider IS NOT NULL and provider_id IS NULL in the users table to
ensure this change is intentional and results match expectations, and confirm
the NOT EXISTS clause that references provider and provider_id uses a NULL-safe
comparison to avoid mismatches when provider_id is NULL.

@dh2906 dh2906 merged commit b27669f into develop Mar 9, 2026
2 checks passed
@dh2906 dh2906 deleted the fix/v43-data-migration branch March 9, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DB DB 마이그레이션을 위한 라벨입니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant