DDD를 공부하면서 도메인 모델 패턴에 대해서 알게 되었다. 그래서 JPA로 기본적인 Aggregate를 구현하고자 한다.
Order라는 Aggregate 안에 각 VO로된 필드들이있다. 배송정보를 포함하는 DeliveryInfo, 주문한 상품목록인 OrderItem, 상품당 가격을 나태난 Money등이 있다.
package com.tddnote.order;
import lombok.*;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
@Access(AccessType.FIELD)
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Money {
private String currency;
@Column(name = "money_value") // 예약어 오류 방지
private int value;
}
import lombok.*;
import javax.persistence.*;
@Embeddable
@Access(AccessType.FIELD)
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class OrderItem {
private String product;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="value", column = @Column(name="price"))
})
private Money price;
}
import lombok.*;
import javax.persistence.*;
@Embeddable
@Access(AccessType.FIELD)
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class DeliveryInfo {
private String address;
private String phone;
}
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ElementCollection
@CollectionTable(name = "order_items", joinColumns = @JoinColumn(name = "order_id"))
private List<OrderItem> items;
@Embedded
private DeliveryInfo deliveryInfo;
}
{
"deliveryInfo": {
"address": "서울시 강남구 언주로 123",
"phone": "010-1234-5678"
},
"items": [
{
"price": {
"currency": "won",
"value": 1000000
},
"product": "아이폰 12 Pro"
},
{
"price": {
"currency": "won",
"value": 1200000
},
"product": "아이폰 12 Pro Max"
}
]
}
ORDERS 테이블
ORDER_ITEMS
JPA를 통해 VO등이 들어간 Aggregate를 간단하게 구현해보았다. VO를 멤버변수로 사용하는 이유는 명료성과 자가 유효성 검사를 통해 Entity의 역할을 좀 더 분리 할 수 있어 확장성에 더 용이하다고 생각한다. mybatis처럼 쿼리로 집어넣는 경우였다면 직접 타입을 적어서 넣어줬어야 했었다. 하지만 JPA와 같은 ORM방식의 장점이 돋보였던 점이 여기서 나타난다. 객체 변수를 따로 조작할 필요가 없이 직관적으로 그대로 적용된다는 것이 돋보였다.