문제가 되는 비즈니스 로직
- 일정 간의 사이클 검사
- Dependency는 from/to 두 개의 schedule을 알고 있다.
- CycleChecker는 그 중 indegree가 0인 임의의 schedule을 잡고, 의존관계를 탐색하며 사이클이 존재하는지를 파악한다.
- 일정 삭제
- 일정 삭제 시, 해당 일정을 알고 있는 모든 의존관계를 제거한다.
- 즉, Dependency 추가와 삭제 모두 관련된 모든 일정이 관리한다.
- 이전 일정이 완료되었는지 확인
- 일정은 이전 일정을 직접 알고있지 않다.
- Dependency라는 엔티티를 거쳐서 알고 있다.
- from.isCompleted()로 사전 완성 일정 체크
- 일정은 이전 일정을 직접 알고있지 않다.
일정 간의 사이클 검사
- 일정 간의 사이클 검사에는 Schedule 정보가 필요하지 않다.
- 따라서, ownerId로 해당 사용자의 모든 연관관계를 가져오고, 위상정렬을 수행하며 사이클이 존재하는지를 검사한다.
Schedule과 Dependency간의 생명주기 관리 방식
- 얼핏 보면 일정이 Dependency를 child entity로 가지면 될 것 같지만, 아래와 같은 이유로 별도의 애그리거트로 지정한다.
- Dependency는 별도의 불변식(사이클 체크)을 갖고 있다.
- Dependency가 삭제되지 않았다고 일정의 삭제를 롤백하는 것은 UX 관점에서 문제가 있다.
- 따라서 두 트랜잭션의 경계를 분리한다.
- 스케줄 참조하는 동안 NPE가 발생하는 문제는 스케줄 쪽에서 잘 처리하는 방식으로 가야 한다.
- 스케줄 삭제 시, 의존은 나중에 따로 삭제되도록 해야 한다.
- 의존이 삭제되지 않았다고 스케줄을 삭제하는 것을 롤백하는 것은 문제가 있다.
- 확실히 의존과 스케줄은 별도의 도메인으로 분리되어야 한다.
- 실제 조회할 시 가져오는 JPQL
SELECT s FROM Schedule s JOIN FETCH s.dependencies d JOIN FETCH d.from f