개인프로젝트를 진행하던 중 엔티티 매핑에 대해 생긴 고민 입니다.
📍 배경

처음 도메인 모델을 분석했을 때:
❶ 도메인 관계 분석
- SMS템플릿과 템플릿변수는 개념적으로 M:N 양방향관계 였다
- 하지만 JPA에서는 M:N 양방향관계 보다 중간 테이블을 명시적으로 모델링 하는것이 권장되므로 SMS템플릿변수관계 엔티티를 하나 생성했다
- SMS템플릿 : SMS템플릿변수관계 = 1:N (양방향)
- SMS템플릿변수관계 : 템플릿변수 = N:1 (양방향)
❷ 연관 관계 최적화
- JPA 성능 최적화를 위해 불필요햔 양방향 관계를 제거했다
- SMS템플릿 : SMS템플릿변수관계 = 1:N (양방향 유지)
- SMS템플릿변수관계 : 템플릿변수 = N:1 (
양방향-> 단방향)

템플릿변수 클래스에서 `mappedBy` 속성을 제거하여 단방향 관계로 변경했다
이는 객체 그래프 탐색 시 불필요한 데이터 로딩을 방지하기 위함이다
유튜브에서 "JPA기초" 최범균님의 강의를 통해 새로운 관점을 접하게 되었다.
강의에서는 연관관계는 보다 값 타입(Embeddable 타입)을 활용한 매핑을 더 권장하고 있었다
이에 기존 코드를 `@ElementCollection`을 활용한 값 컬렉션 매핑으로 변경할 수 있을지 고민하게 되었다
📍 연관 매핑 vs 값 컬렉션 매핑 비교
| 구분 | 연관매핑 (@OneToMany, @ManyToOne) | 값컬렉션매핑 (@ElementCollection) |
| 저장 방식 | 별도의 테이블과 외래 키(FK)를 사용하여 관계를 맺음 | 별도 엔티티 없이 컬렉션을 저장하는 테이블을 사용 |
| 엔티티 여부 | 연관된 대상이 엔티티 (PK가 필요) | 엔티티가 아닌 값 타입 (PK 필요 없음) |
| 변경 추적 | 엔티티이므로 JPA의 변경 감지를 받을 수 있음 | 값 타입이라 변경 감지 불가능, 통째로 삭제 후 다시 저장됨 |
| 성능 | 조인이 필요하여 성능 부담이 있을 수 있음 | 단순한 조회에서는 성능이 유리하지만 데이터가 많아지면 성능 저하 가능 |
| 활용예시 | `Order` ↔ `OrderItem`처럼 독립적인 엔티티로 관리해야 하는 경우 | 한 엔티티 내에서 간단한 리스트(주소 목록, 태그 등)를 저장하는 경우 |
연관매핑의 장단점 분석
장점
- 템플릿과 변수 간의 관계를 명확하게 표현할 수 있어 유지보수성이 높습니다.
- 템플릿이 하나일 때 여러 변수들이 확실하게 연결되며, 나중에 템플릿에 대한 변경 사항을 쉽게 추적할 수 있습니다.
- 템플릿 변수의 변동이 있을 때 연관된 데이터를 관리하기 용이합니다.
단점
- 데이터베이스에서 관계를 맺으므로, 불필요하게 복잡한 조인이나 성능 저하가 있을 수 있습니다.
값 컬렉션 매핑의 장단점 분석
장점
- 템플릿과 템플릿 변수가 밀접하게 결합되어 있어서, 관련된 데이터들이 한 번에 처리됩니다.
- 복잡한 관계를 피할 수 있고, 단순히 템플릿 데이터를 저장하는 데 유리합니다.
- 템플릿 변수가 변동이 자주 있는 경우 유리할 수 있습니다.
단점
- 엔티티로 모델링한 것처럼 유연성이 떨어질 수 있습니다. 예를 들어, 템플릿변수를 별도로 조회하거나 관리하기 어려워질 수 있습니다.
- 데이터가 늘어날수록 컬렉션을 DB에 저장하는 데 성능상의 문제가 발생할 수 있습니다.
📍 값 컬렉션 매핑으로 변경하던 중 생긴 문제
SMS템플릿과 템플릿변수가 변경될 가능성이 적기 때문에 값 컬렉션 매핑으로 코드를 변경하고 전후 성능 비교를 하려고 했다
그러나 ... 소스코드 작성 중 중요한 문제에 직면했다


SMS 템플릿 도메인 클래스에는 관계를 관리하는 메소드가 있어 도메인 모델이 직접 비즈니스 로직을 수행하도록 구현했다
비즈니스 로직에서 기존 템플릿 변수가 존재하는 경우에만 관계를 추가하도록 조건을 가지고 구현했다
그러나 값 컬렉션 매핑으로 변경할 경우, Embeddable 클래스는 고유 식별자(ID)를 가지지 않아 JPA Repository를 통한 존재 여부 확인이 불가능해졌다
📍 최종 결정

JPA 기초 17 영속성 전파 & 연관 고려사항 을 보면 위와 같은 좋은 질문댓글과 답댓글이 있어서 가져왔다
이전에는 읽어도 100%이해하기 어려웠는데 이렇게 실습을 해보니 이제는 이해가 간다
템플릿 변수를 `@Entity`로 관리해야 하는 이유를 더 나열해보자면
1. 고유 식별자 필요: 템플릿 변수는 여러 SMS 템플릿에서 재사용될 수 있으며, 이를 위해 고유 식별자가 필요하다.
2. 독립적인 생명 주기: 템플릿 변수는 특정 템플릿에 종속되지 않고, 여러 템플릿에서 공통으로 사용될 수 있다.
3. 도메인상의 독립성: 템플릿 변수는 이름, 전화번호 등 여러 템플릿에서 활용될 수 있는 값이며, 관리 대상이 될 수 있다.
4. 명시적인 관계 설정: 템플릿 변수를 템플릿에 저장할 때마다 관계를 설정하는 로직이 존재한다.
따라서 템플릿 변수는 밸류 객체가 아니라 독립적이고 재사용 가능한 엔티티로 작성하는게 더 적합하여 코드 변경 없이 연관관계로 매핑을 쭉 이어나갈 예정이다
📍 마무리 및 느낀점
결론적으로
- 도메인 특성에 기반한 선택이 중요하다:
- 템플릿 변수가 자주 변경되거나 독립적으로 관리될 필요가 있다면 → 연관 매핑
- 템플릿과 함께 항상 사용되고 독립적인 의미가 적다면 → 값 컬렉션 매핑
- 식별자의 필요성이 가장 중요한 판단 기준이다:
- 고유 식별자가 필요하다면 → 엔티티와 연관 매핑
- 식별자 없이 소유 엔티티에 종속적이라면 → 값 타입과 값 컬렉션 매핑
- 성능과 유지보수성의 균형을 고려해야 한다:
- 값 컬렉션은 단순하고 성능이 좋을 수 있지만 유연성이 떨어진다
- 연관 매핑은 복잡할 수 있지만 더 많은 유연성과 세밀한 제어를 제공한다
처음에는 이론만 듣고 연관 관계 매핑과 값 컬렉션 매핑 중 어떤 방식이 더 적합한지 판단하기 어려웠다.
강의에서는 각 방식의 장단점을 설명하지만, 실제 프로젝트에 적용하려니 결정이 쉽지 않았다.
그러나 직접 두 방식으로 코드를 구현해보면서 각 접근법의 실질적인 한계점과 강점을 체감할 수 있었다.
연관 관계 매핑은 엔티티 간 관계를 명확히 표현할 수 있어 유지보수성이 높았다.
특히 복잡한 비즈니스 로직과 제약조건을 규현하기 용이했으며, 개별 객체의 세밀한 제어가 가능했다
하지만 관계를 설정할 때 필요한 코드가 비교적 많았고 서비스에서 도메인 레이어로 넘겨줘야 하는 파라미터(레포지토리)가 많아졌다는 점이 있다
값 컬렉션 매핑은 코드가 단순하고 직관적이었다.
관계를 추가할 때 바로 Set컬렉션에 add를 해주면 되어 코드를 이해하기 편했고 연관 관계 설정 코드가 필요 없어 전체적인 코드량도 줄었다
하지만 별도 엔티티 조회나 복잡한 제약조건을 구현하기 어려웠고, 컬렉션 전체를 한번에 관리해야 하는 단점이 있었다.
결국 실제 구현을 통해 도메인의 특성과 요구사항에 따라 적합한 매핑 방식이 달라진다는 것을 몸소 체험했다. 이론적 지식보다 실제 코드로 구현해보고 장단점을 경험해보는 것이 더 깊은 이해로 이어진다는 것을 다시 한번 깨달았다.
'Data' 카테고리의 다른 글
| 금융권에서 오라클 DBMS를 선택하는 이유 (6) | 2025.08.01 |
|---|---|
| JPA 복합키 엔티티에서 단일 필드 조회 문제 해결하기 (3) | 2025.04.01 |
| JpaRepository를 상속받으면 @Repository 어노테이션을 안달아도 되는 이유 (0) | 2025.03.26 |
| 데이터 마이그레이션이란? (2) | 2024.09.26 |