첫번째 트러블슈팅
[Error] 일정 관리 트러블 슈팅 1 - 제네릭
제네릭이 개념중에 가장 코드 적용으로 바로 이어지기 힘든 부분이었다. 필수과제 구현까지 총 3번의 제네릭 활용 리팩토링을 해보았는데 그 과정에서 시행착오가 많았기 때문에 정리해보려고
devz0.tistory.com
문제
리팩토링을 진행하며 User, Schedule, Comment 세 도메인 간 연관관계를 다시 보던 중, “단방향으로 유지할지, 양방향으로 전환할지” 판단이 애매했다. 특히, 단건 조회에서 일정과 댓글을 함께 보여주는 엔드포인트 설계를 하며 “일정 단건 조회시 댓글목록을 항상 참조하는데 Schedule ↔ Comment를 양방향으로 바꿔야 하나?”라는 고민이 있었다.
⚠️ 이전입문과제는 일정과 댓글을 양방향 매핑으로 관계를 설정했다. 뭔가를 알고 했다기 보다 강의대로 진행하다보니 그대로 따라갔다. 단순히 데이터가 함께 필요하다는 이유로 양방향 매핑을 하면 다음과 같은 일이 발생한다.
- @JsonIgnore 등 직렬화 이슈 발생 -> 내가 저번입문과제에 겪었던 문제!
- 그대로 JSON으로 직렬화할 경우, 스프링의 Jackson이 두 엔티티를 서로 무한히 순환하며 직렬화하려고 시도
- 순환참조 위험 (Schedule → Comment → Schedule) -> 내가 저번입문과제에 겪었던 문제!
- 양방향 매핑을 걸면 객체 그래프가 서로 참조 하면서 StackOverflowError 또는 Infinite recursion 예외가 발생
- fetch join 과 Pagination 충돌
- 한 페이지에 10개의 일정만 보여줘야 하는데 실제 쿼리는 JOIN된 댓글 row 수만큼 곱해져서 페이지네이션이 무의미해지는 상황 발생
- 도메인 간 의존성이 뒤얽혀 테스트 및 유지보수 어려움
- 양방향을 무분별하게 설정하면 도메인 간의 경계가 모호해진다.
예를 들어 Schedule이 Comment를 알고, Comment가 다시 Schedule을 알면, 어느 쪽이 데이터를 주도하는 루트(Aggregate Root)인지 헷갈리게 된다. - 도메인은 책임 단위로 분리돼야 하는데, 양방향이 많아지면 결국 모든 게 연결된 거대한 그래프가 되어버린다.
- 양방향을 무분별하게 설정하면 도메인 간의 경계가 모호해진다.
해결 과정
1. 탐색의 주체 파악
- 일정 단건 조회 시 댓글 목록도 함께 본다 → 주체는 Schedule
- 댓글이 어떤 일정에 속했는지 알고 싶다 → 주체는 Comment
👉🏻 탐색 방향이 한쪽(Comment)에서만 필요하면 단방향 유지
2. 조회 구분
- 단건 조회 (GET /schedules/{id}): 상세 페이지, 댓글 필요
- 다건 조회 (GET /schedules): 목록 페이지, 댓글 불필요
👉🏻 단건 조회 시만 댓글 필요 → commentRepository.findAllByScheduleId() 호출로 해결
👉🏻 다건 조회에서 fetch join 시도는 금지 (성능 저하 + row 중복), fetch join과 Pagination 함께 사용할 수 없음
3. 도메인 역할 점검
- 댓글의 생성·수정·삭제 책임은 CommentService
- 일정은 댓글의 존재를 몰라도 로직이 성립됨
- 따라서 도메인 간 의존성을 추가할 이유가 없음
4. 결론
- 단건 조회 시 댓글 포함은 단방향 + 커스텀 쿼리 메서드로 충분
- 양방향 전환은 일정에서 댓글을 자주 탐색하는 시점(즉, 항상 함께 조회되는 시점)에만 고려
추가적으로 Comment와 User도 세션 기반 검증으로 충분하다고 판단해 단방향이 맞다고 생각했다.
배운점
관계 설정은 탐색 주체와 조회 빈도로 결정한다.
- 단건 상세 조회만 댓글이 필요하다면, 단방향 + 쿼리 메서드 접근이 구조적으로 맞다.
- 다건 조회에서 무의식적으로 fetch join을 쓰면 성능 문제가 발생한다.
양방향을 대체 그럼 언제쓰는걸까 단방향 양방향 차이만 계속 검색했다. 단순히 문법적으로만 접근을 해서 그랬던 것 같다. 양방향을 써야하는 기준을 객체 탐색의 방향을 보고 조회 패턴의 빈도로 생각하며 현재 단방향이 단건조회에서 기본 select문 1개에 댓글 조회해 목록에 담는 쿼리1번 두번이 일어나더라도 다건조회에선 쓰이지않고 페이지네이션을 적용해야 했기때문에 적절하다고 스스로 판단했다.
또한 관계설정을 관계를 추가한다로 보는것이 아니라 이 객체가 관계맺을 객체를 알아야하나? 를 고민하게 되었다.
'BootCamp' 카테고리의 다른 글
| [Error] 일정 관리 트러블 슈팅 1 - 제네릭 (0) | 2025.11.12 |
|---|---|
| [Error] 일정 트러블 슈팅 (1) | 2025.11.05 |
| [내배캠] 한달 회고 (0) | 2025.10.31 |
| [Error] 키오스크 트러블 슈팅 3 - 장바구니 구조 설계 (0) | 2025.10.28 |
| [Error] 키오스크 트러블 슈팅 2 -책임 분리 (0) | 2025.10.27 |