일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 달팽이
- Spring Cloud Config
- 메모이제이션
- 백트래킹
- 이분 매칭
- Logback
- 게이트웨이
- spring boot
- 트리
- 주울
- 서비스 디스커버리
- 구현
- 완전 탐색
- Gradle
- 다익스트라
- 구간 트리
- dp
- BFS
- 플로이드 와샬
- Zuul
- 비트마스킹
- ZuulFilter
- 도커
- 유레카
- Java
- 스택
- 스프링 시큐리티
- docker-compose
- 이분 탐색
- spring cloud
- Today
- Total
Hello, Freakin world!
M:N 매핑의 중간 테이블. 어떤 패키지에 있어야 될까? 본문
최근 토이 프로젝트 엔티티 모델을 설계하면서 든 생각입니다.
User(사용자) 라는 엔티티가 있고, Project(프로젝트) 라는 엔티티가 있다고 합시다.
- 사용자는 다수 프로젝트에 참여할 수 있습니다.
- 하나의 프로젝트에 다수의 사용자가 참여할 수 있습니다.
위 두 가지 요구사항으로 인해 User와 Project가 M:N 관계라는걸 알 수 있습니다.
DB 데이터 모델을 설계할 때, 이런 M:N 관계를 풀기 위해서 보통 `중간 테이블` 이라는 걸 두게 됩니다.
중간 테이블의 이름은 무난하게 짓는다면 user_project 정도가 되겠지요.
DDD를 배우고나서 다시 바라보니 여기에 한가지 의문이 생깁니다.
User와 Project의 도메인은 서로 다르기 때문에 패키지가 서로 분리돼있습니다.
UserProject(중간 테이블의 엔티티)는 어떤 패지키에 위치해야 할까요?
제가 만들려는 비지니스 로직에서는 사용자 쪽에서 프로젝트 참여 등의 여부를 정하기 때문에, 사용자 도메인에 더 가깝다고 볼 수 있지만...
사실 user 패키지 아래에 두더라도, UserProject를 User와 Project에서 필드 매핑으로 UserProject 참조를 들고 있기 때문에,
어디에 두더라도 그 의미가 크진 않습니다.
더 나아가서, 서로 다른 도메인 각각의 루트 애그리거트의 연결 테이블이 공유되는게 맞는건가? 라는 의문이 들었습니다.
UserProject 역할의 테이블이 각각 user와 project 패키지 밑에 있는건 어떨까요? 중간 테이블을 공유하는게 아니라 도메인 별로 각각 하나를 가지는거죠.
이름을 바꿔서 user 패키지에는 JoinProject, project 패키지에는 JoinUser 라고 합시다.
이렇게 할 경우, 도메인 간의 관계를 확실히 끊어낼 수 있습니다.
그리고 UserProject라는 애매한 이름의 엔티티가 아닌 좀 더 명확한 이름의 중간 엔티티의 이름 사용이 가능합니다.
(사용자 도메인에서 JoinProject는 참여한 프로젝트, 프로젝트 도메인에선 JoinUser는 참여한 사용자가 됩니다.)
하지만 도메인 간의 관계가 끊어지기 때문에, 각각 중간 데이터의 일관성에 대한 이슈를 해결해야 합니다.
이 부분은 보통 이벤트 주도 방식을 이용해 해결하는 듯합니다.
'JPA' 카테고리의 다른 글
간단한 QueryDSL 초기 설정 in Gradle 6 (0) | 2021.03.02 |
---|