도메인 모델을 먼저 보는 보수적인 JPA 연관관계 설계
ID에서 시작하고 생명주기가 실제로 맞을 때만 연관관계를 추가하며, 비즈니스 개념은 엔티티와 독립적으로 표현하는 방법을 다룹니다.
출처 및 AI 안내: 이 글은 제미니의 개발실무 유튜브를 기반으로 작성되었습니다.
gpt-5.6-sol모델을 사용해 생성·편집했습니다.
JPA는 엔티티를 연결하기 쉽게 만들어 준다. 그렇다고 데이터베이스에 존재하는 모든 관계를 객체 연관관계로 옮겨야 하는 것은 아니다. 나는 관련 ID만 들고 연관관계 없이 시작한다. 그 관계가 모델 안에 꼭 있어야 한다는 사실이 확인된 뒤에야 매핑을 고민한다.
여러 힘든 시스템을 겪고 생긴 보수적인 기본값일 뿐, 정답이라고 주장하는 규칙은 아니다. 연관관계를 잘 다루는 팀이라면 그대로 써도 된다. 중요한 것은 JPA가 지원한다는 이유만으로 관계를 먼저 늘리지 않는 것이다.
우선 ID만 둔다
리뷰와 리뷰 이미지가 있다고 해보자. 보통은 이미지가 리뷰 ID를 들고 있게 한 뒤 연관관계를 맺지 않고 시작한다. 이 상태에서 필요해진 매핑을 추가하는 일은 어렵지 않다. 반대로 양방향 연관관계가 여러 곳에 퍼진 뒤에는 탐색 방향과 로딩 방식, 비즈니스 코드까지 그 그래프에 기대기 때문에 되돌리기 어렵다.
연관관계를 걸 때 가장 먼저 보는 조건은 생명주기다. 둘이 항상 함께 생기고 사라지는가? 부모가 실제 업무를 수행하려면 자식을 반드시 알아야 하는가? 리뷰와 이미지도 정책에 따라 답이 달라진다. 이미지 없는 리뷰가 존재할 수 있고, 한 리뷰에 붙는 이미지 수가 달라질 수도 있다.
그래서 기본값은 좁다.
- 양방향 매핑은 피한다.
- 일대다와 일대일은 특히 조심한다.
- 생명주기와 필요한 탐색 방향을 확인한 뒤 단방향 다대일을 검토한다.
이 역시 금지 목록은 아니다. 어떤 비즈니스에서 주문과 주문 항목이 늘 한 덩어리라면 더 가까운 매핑이 맞을 수 있다. 기준은 JPA의 기능 목록이 아니라 실제 비즈니스 관계여야 한다.
엔티티 모양이 도메인 모델을 결정하지 않는다
엔티티마다 필드까지 똑같은 도메인 객체가 하나씩 있어야 한다고 생각하면 또 다른 제약이 생긴다. 엔티티는 저장 방식을 표현하고, 도메인 모델은 비즈니스가 다루려는 개념을 표현한다.
질문과 답변이 별도 엔티티로 저장되는 경우를 보자. 답변이 질문 ID를 가지고 있어도 두 엔티티가 서로 탐색할 필요는 없다. 반면 도메인에서는 질문과 선택적인 답변을 묶은 Q&A가 업무에 더 의미 있는 단위일 수 있다. 영속성 매핑에 관계가 없어도 도메인 객체는 그 개념을 자유롭게 보여줄 수 있다.
리뷰와 이미지도 같다. 용도에 따라 리뷰만 내보낼 수도 있고, 리뷰와 이미지가 결합된 별도 개념을 만들 수도 있다. 어떤 이름과 모양이 비즈니스를 가장 또렷하게 설명하는지 여러 형태를 시도하면 된다. 엔티티 그래프를 그대로 복제할 이유는 없다.
두 결정을 분리한다
엔티티 매핑과 도메인 모델링은 서로 영향을 주지만 질문은 다르다.
- 영속성에서 어떤 연관관계가 안전하고 유용한가?
- 어떤 객체 모양이 비즈니스 행위를 분명하게 설명하는가?
둘을 나누면 변경할 여지가 생긴다. 테이블이나 엔티티가 바뀌어도 모든 도메인 객체가 따라 움직일 필요가 없다. 도메인 표현을 바꿔 보려고 먼저 영속성 그래프부터 뜯을 필요도 없다.
나는 빽빽한 연관관계에서 빠져나오느라 애쓰기보다 적은 관계로 시작하고 필요한 관계를 나중에 발견하는 쪽을 택한다. 모든 팀에 맞는 답은 아니지만, 적어도 설계의 중심을 JPA가 아니라 실제 비즈니스 관계에 둘 수 있다.