해당 포스팅은 최범균 작가님의 도메인 주도 개발 시작하기 (P.139~142)를 읽고 정리한 글입니다.
매핑 구현
엔티티와 밸류 기본 매핑 구현
애그리거트와 JPA 매핑을 위한 기본 규칙은 다음과 같다.
- 애그리거트 루트는 엔티티이므로 @Entity로 매핑 설정한다.
한 테이블에 엔티티와 밸류 데이터가 같이 있다면
- 밸류는 @Embeddable로 매핑 설정한다.
- 밸류 타입 프로퍼티는 @Embedded로 매핑 설정한다.
주문 애그리거트를 예로 들자면, 주문 애그리거트의 루트 엔티티는 Order이고 이 애그리거트에 속한 Orderer과 ShippingInfo는 밸류이다. 이 세 객체와 ShippingInfo에 포함된 Address 객체와 Receiver 객체는 다음과 같이 한 테이블에 매핑할 수 있다.
주문 애그리거트에서 루트 엔티티인 Order는 JPA의 @Entity로 매핑한다.
@Entity
@Table(name = "purchase_order")
public class Order {
...
}
Order에 속하는 Order는 밸류이므로 @Embeddable로 매핑한다.
@Embeddable
public class Orderer {
// MemberId에 정의된 컬럼 이름을 변경하기 위해 @AttributeOverride 사용
@Embedded
@AttributeOverrides (
@AttributeOverride(name = "id", column = @Column(name = "orderer_id"))
)
private MemberId memberId;
}
Orderer의 memberId는 Member 애그리거트를 ID로 참조한다. Member의 ID 타입으로 사용되는 MemberId는 다음과 같이 id 프로퍼티와 매핑되는 테이블 칼럼 이름으로 "member_id"를 지정하고 있다.
@Embeddable
public class MemberId implements Serializable {
@Column(name ="member_id")
private String id;
}
@Embeddable 타입에 설정한 컬럼명과 실제 컬럼명이 다르므로 @AttributeOverrides 애너테이션을 이용해서 Orderer의 memberId 프로퍼티와 매핑할 컬럼명을 변경했다.
루트 엔티티인 Order 클래스는 @Embedded를 이용해서 밸류 타입 프로퍼티를 설정한다.
@Entity
public class Order {
@Embedded
private Order order;
@Embedded
private ShippingInfo shippingInfo;
}
@Embeddable과 @Embedded, 그리고 @AttributeOverrides를 활용해 컬럼명을 자유롭게 조장할 수 있다는 점이 인상적이었다. 도메인명과 데이터베이스 스키마 간 불일치를 깔끔하게 해소할 수 있어, 객체와 테이블 간 매핑의 유연성이 크게 향상된다는 사실을 깨달았다.