Skip to content

Conversation

@nayonsoso
Copy link
Collaborator

@nayonsoso nayonsoso commented Aug 2, 2025

관련 이슈

트러블 슈팅 과정

멘토의 마이 페이지 수정 시, 채널을 변경할 때 'unique 제약조건 위반'이 발생했습니다.
image

Channels 엔티티를 보면 아시겠지만, mentor_id와 sequence 조합으로 unique 제약조건을 설정해둔 상태였습니다.
코드 자체만 봤을 때는 “🤔removeAll 후 add 를 하고 있으니, 문제가 없지 않나?” 싶었습니다.

// 이전 코드
public void updateChannels(List<Channel> channels) {
    this.channels.clear();
    if (channels == null || channels.isEmpty()) {
        return;
    }
    for (Channel channel : channels) {
        channel.updateMentor(this);
        this.channels.add(channel);
    }
}

Hibernate 공식 문서에도 컬렉션에 있어서는 delete 문이 먼저 실행된다고 되어있어, 원인을 파악하기 어려웠습니다..
image

진짜 문제는 기존의 코드에서는 new Channel()로 완전히 새로운 객체를 만들어 넣었다는 것이었습니다.
이때문에 4번인 insertion of collection elements 가 아니라 1번의 insert로 인식되어서 delete 보다 먼저 실행되었습니다.

이 문제를 해결하기 위해

  • 기존의 채널을 업데이트
  • 기존보다 새로운 채널의 수가 많다면, 채널 추가
  • 기존보다 새로운 채널의 수가 적다면, 채널 삭제

를 하도록 코드를 수정했습니다.

또한 테스트 코드를 보충했습니다.

@nayonsoso nayonsoso self-assigned this Aug 2, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 2, 2025

Walkthrough

  1. Channel 클래스에 update 메서드 추가
      - Channel 클래스에 다른 Channel 객체의 sequence, type, url 값을 복사하는 public update(Channel channel) 메서드가 새로 추가되었습니다.
  2. Mentor 클래스의 updateChannels 메서드 로직 개선
      - 기존에 채널 리스트를 모두 지우고 새로 추가하던 방식을 버리고, 인덱스별로 기존 채널을 업데이트하거나 새 채널을 추가, 불필요한 채널은 제거하는 방식으로 변경되었습니다.
  3. 테스트 코드 분리 및 검증 방식 개선
      - MentorMyPageServiceTest에서 채널 업데이트 테스트가 기존 하나에서 두 개(적은 채널, 많은 채널)로 분리되었고, 채널의 sequence, type, url을 한 번에 검증하는 AssertJ의 tuple 검증으로 간결하게 개선되었습니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Suggested reviewers

  • wibaek
  • lsy1307

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 63b6b1e and e6dffc9.

📒 Files selected for processing (3)
  • src/main/java/com/example/solidconnection/mentor/domain/Channel.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/Mentor.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/main/java/com/example/solidconnection/mentor/domain/Channel.java
  • src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java
  • src/main/java/com/example/solidconnection/mentor/domain/Mentor.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

coderabbitai[bot]

This comment was marked as outdated.

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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 473739a and 2935a99.

📒 Files selected for processing (3)
  • src/main/java/com/example/solidconnection/mentor/domain/Channel.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/Mentor.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/com/example/solidconnection/mentor/domain/Channel.java
  • src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: nayonsoso
PR: solid-connection/solid-connect-server#375
File: src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java:47-53
Timestamp: 2025-07-05T17:54:42.475Z
Learning: MentorMyPageService에서 PUT 메서드 구현 시 전체 채널을 새로 생성하여 교체하는 방식을 사용하는 것이 PUT의 의미론적 특성과 일치하며, 트랜잭션 로킹 관점에서도 합리적인 접근이다.
📚 Learning: mentormypageservice에서 put 메서드 구현 시 전체 채널을 새로 생성하여 교체하는 방식을 사용하는 것이 put의 의미론적 특성과 일치하며, 트랜잭션 로킹 관점에서도...
Learnt from: nayonsoso
PR: solid-connection/solid-connect-server#375
File: src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java:47-53
Timestamp: 2025-07-05T17:54:42.475Z
Learning: MentorMyPageService에서 PUT 메서드 구현 시 전체 채널을 새로 생성하여 교체하는 방식을 사용하는 것이 PUT의 의미론적 특성과 일치하며, 트랜잭션 로킹 관점에서도 합리적인 접근이다.

Applied to files:

  • src/main/java/com/example/solidconnection/mentor/domain/Mentor.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (1)
src/main/java/com/example/solidconnection/mentor/domain/Mentor.java (1)

67-83: 승인: Channel.update()에서 sequence 필드를 포함한 모든 속성 업데이트가 확인되었습니다.
Shell 스크립트 결과, update 메서드가 sequence, type, url을 모두 올바르게 복사함을 검증했습니다.
기존 채널 업데이트, 새 채널 추가, 초과 채널 제거 로직이 유니크 제약을 안전하게 유지합니다.
머지 진행 부탁드립니다.

변경 사항 요약:

  1. Channel.update() 검증
    • sequence, type, url 복사 확인
  2. 기존 채널 업데이트
    • this.channels.get(i).update(channel)로 안전한 동기화
  3. 새 채널 추가
    • updateMentor() 호출 후 리스트 끝에 추가
  4. 초과 채널 제거
    • 뒤에서부터 순차적으로 remove 호출

@nayonsoso nayonsoso force-pushed the fix/424-update-channels branch from 2935a99 to 63b6b1e Compare August 2, 2025 21:48
@nayonsoso nayonsoso added the 버그 Something isn't working label Aug 2, 2025
@nayonsoso nayonsoso force-pushed the fix/424-update-channels branch from 63b6b1e to e6dffc9 Compare August 2, 2025 21:58
Copy link
Member

@whqtker whqtker left a comment

Choose a reason for hiding this comment

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

좋은 변경입니다 !
clearflush 를 수행해도 과연 동일하게 동작할까요 ..?

@nayonsoso
Copy link
Collaborator Author

clear 후 flush 를 수행해도 과연 동일하게 동작할까요 ..?

@whqtker 네 맞습니다! 다만 영속성 컨텍스트를 주입받아야 한다는 점이 걸렸어요😅

@nayonsoso nayonsoso merged commit 9c7249c into solid-connection:develop Aug 3, 2025
2 checks passed
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: 멘토가 채널 변경 시 발생하는 문제 해결

3 participants