Search

JPA의 사실과 오해 (7) 애그리거트와 연관관계

Tags
Study
JPA
Database
Last edited time
2025/07/21 08:35
2 more properties
Search
JPA의 사실과 오해 (8) 컬렉션로딩 문제 (지연/즉시 로딩)
Study
JPA
Database
JPA의 사실과 오해 (8) 컬렉션로딩 문제 (지연/즉시 로딩)
Study
JPA
Database

1. 애그리거트와 연관관계

1.1. 기본 개념

아래 링크로 대체

1.2. 캡슐화 기준

JPA를 사용하면서 발생하는 많은 문제의 원인
객체 그룹 사이에 경계가 없이 모든 객체가 동일한 수준에서 연결
객체를 그룹으로 묶어 캡슐화시킨 후 그룹 단위로 설정 적용
불변식 (Invariant)을 기준으로 그룹화
언제나 일관되게 유지돼야하는 비즈니스 규칙
불변식은 트랜잭션 일관성과 관련

2. 애그리거트

2.1. 기본 개념

불변식을 만족시키는 객체 그룹 단위로 처리
실제 애그리거트는 불변식 관점 / 같이 체크해서 상태를 바꿔야함
컴포지션 / 컨테이너의 관점
어떤 객체가 특정 객체(A) 를 가지고 있는가?
외부에서는 애그리거트 루트에만 접근
애그리거트에 대한 상세한 설명은 상단 링크 참조

2.2. 경합 지점의 경계

경합이 발생하는 영역
A라는 객체와 B라는 객체가 묶여있는 것처럼 보이지만, 실제로는 따로따로 업데이트 되는 순간이 있음
1번 예시
주문이 이루어지면 사용자 마일리지를 쌓아줘야함
주문과 사용자 마일리지는 애그리거트인가?
주문의 수정 빈도와 사용자 생성/수정 빈도는 완전히 다름
주문이 업데이트 되는 주기와 사용자가 업데이트 되는 주기는 완전히 다름
두 객체를 동일한 애그리거트로 묶게되면 경합이 발생
2번 예시
상품
여러 도메인에서 사용되는 객체임 (예를 들어, 주문)
여러 곳에서 사용된다는 말은 경합이 발생한다는 것을 의미 → 정리 필요
주문과 상품은 완전히 수정하는 주기가 다름
주문이 수정되면 상품이 수정되는것처럼 보이나 정말 애그리거트인지 고민필요
수정하는 경계에 따라 애그리거트 설정하는것이 좋음
단일 트랜잭션 내부에서 처리할건지? 궁극적 일관성으로 처리할건지 고민 필요
애그리거트는 보통 사용자 1명이 업데이트 침
주문 → 고객이 업데이트
메뉴 → 사장님이 업데이트
다양한 사용자가 업데이트하는 경우는 거의 없음
수정되는 곳이 많다는 것은 경합이 발생한다는 것을 의미하므로 정리가 필요 수정되는 빈도 / 주기에 따라 나누는것이 좋음 애그리거트는 보통 1명의 유저가 업데이트하는 것이 일반적

2.3. JPA 영속성 전파 설정

캡슐화 경계를 정하면 그 경계를 기준으로 일관적으로 JPA룰을 설정하면 됨
애그리거트 하위 도메인 객체인 경우
CascadeType.ALL
애그리거트 전체는 함께 저장/수정/삭제
공유 참조와 배타적 소유권
배타적 소유권을 가지고 있다면 외부에서 참조하는 경우가 없음
orphanRemoval = true 설정 가능
애그리거트라는 개념이 중요한 것이 아님. 캡슐화의 경계를 세우는것이 핵심 캡슐화의 경계를 세워서 일관성있는 JPA 룰 설정 필요 객체지향을 하려면 JPA 룰을 단순화하는게 좋음. 룰 설정은 결국 설계의 관점

3. 연관관계 단순화

3.1. 개념

연관관계는 메세지를 보낼 때 쓰는것
FK가 있다고 해서 무조건 관계를 세울 필요가 없음
애그리거트 사이에는 연관관계 단순화 하는 룰을 세우는게 좋음

3.2. 연관관계 단순화 룰

1.
탐색방향 부여하기
애그리거트간의 관계는 단방향 연관관계를 설정하는게 좋음
애그리거트 내부의 연관관계는 양방향 관계를 설정해도 상관 없음
2.
다중성 줄이기
다중성은 줄이는게 좋음
루트 애그리거트에서 Collection을 항상 들고 다니기 vs 하위 도메인 객체가 루트 애그리거트 참조
3.
중요하지 않은(불필요한) 연관관계 제거하기

4. 기타 질문

전체 서비스에 상품이라는 도메인 객체가 하나만 존재?
상품이 1개만 있다면 잘못 된 것
바운디드 컨텍스트마다 상품을 찢어야 함 (경합 제거)
단일 Repo (MonoRepo) 이면서, 바운디드 컨텍스트마다 상품이라는 개념이 각각 다르다면?
하나의 테이블에 여러 클래스를 나누거나, 혹은 별도의 테이블로 나눌 수도 있음
바운디드 컨텍스트 마다 여러 클래스를 나누더라도 하나의 테이블을 바라보고 있다면 트랜잭션주기에 따라서 락이 발생할 수있지 않는지?
이건 사실 테이블 하나에 하나의 클래스를 쓰더라도 마찬가지로 발생할 수 있는 문제임
만약 그러한 상황이 지속적으로 발생한다면 테이블 분리하는것을 권장