값 타입이 뭔가 싶지만 초반에 엔티티 매핑에서 테이블 단위의 매핑을 했다면 이번에는 컬럼 단위의 매핑에 관한 내용이었다. 어떻게 매핑한다는 내용보다는 Object 관점에서 일반적으로 사용하는 컬럼의 타입 말고 조금 더 세밀한 객체 모델링을 할 수 있는 방법에 대해서 다뤘다.
실무에서 많이 사용해온 부분이라서 엄청 자세하게 정리할 필요까지는 없을 것 같지만 기본적인 내용들은 정리를 하려고 한다.
@Embedded, @Embeddable
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
//period
@Embedded
private Period period;
//address
@Embedded
private Address homeAddress;
}
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
public Address() { // 기본생성자 필수
}
}
@Embeddable
public class Period {
private LocalDateTime startDate;
private LocalDateTime endDate;
public Period() { // 기본생성자 필수
}
}
당연한 이야기지만 @Embeddable 도 엔티티와 관계를 맺을 수 있다. 결국 @Embeddable 의 필드들이 @Embedded 가 선언된 곳에 귀속 되므로 @Embeddable 에 @OneToMany 등 엔티티와 관계 설정을 하는 행위 자체가 애초에 @Embedded 에 관계 설정을 한 것과 동일하다.
앞서 정리한 @Embeddable 도 그렇고 DDD 에서 말하는 애그리거트를 구성하는 엔티티와 밸류 객체 모두 결국 마틴 파울러가 말하는 Value Object 로 구현하는 것이 이상적이다. 책에는 불변 객체의 이점에 대해서 설명되어 있는데, Value Object 가 불변으로 설계가 되어있다.
정리가 잘 된 포스팅들이 여럿 있는데 이 보기가 편한 것 같아서 링크를 남긴다. 필드들을 묶을 수 있는 논리적 단위가 있다면 Value Object 로 만들어서 묶어 주는 것이 더 세밀한 객체 모델링에 가까워지는 것이라고 생각 된다. 생성시 validation 도 각 객체에서 책임을 더 세밀하게 나눠서 처리할 수 있고, 불변 객체로 만들어서 객체를 더 신뢰하고 사용할 수 있다.
자바 14에 프리뷰로 공개되고 16부터 정식 스펙이 된 가 Value Object 의 조건들을 만족시킨다. 즉, Value Object 를 손쉽게 만드는 방법으로 자바의 record 를 사용할 수 있다. 이 있어 링크를 남긴다.