Icednut's Note

나만의 책속 한 줄 - 책 'DDD Start!'를 읽으면서...

2016-08-03

예를 들어, 게시글 데이터를 ARTICLE 테이블과 ARTICLE_CONTENT 테이블로 나눠서 저장한다고 하자.

(중략)

[그림4.5]만 보면 ARTICLE_CONTENT 테이블의 ID 칼럼이 식별자이므로 ARTICLE_CONTENT와 맵핑되는 ArticleContent를 엔티티로 생각할 수 있는데, 이것 때문에 Article과 ArticleContent를 두 엔티티 간의 일대일 연관으로 매핑하는 실수를 할 수 있다.

책을 읽다말고 ‘아니 이게 왜 실수인가?’ 라는 생각이 퍼뜩 들었다. 왜냐하면 평소에도 Article과 ArticleContent는 각각 엔티티로 만들어서 연관관계를 맺어줘야 한다고 생각했기 때문이다. 그런데 그 다음을 읽자 내가 생각없이 코딩하고 있었다는 것이 여실히 들어나게 되는 순간을 맞이하게 되었다.

ArticleContent를 엔티티로 생각할 수 있지만 ArticleContent는 Article의 내용을 담고 있는 밸류로 생각하는 것이 맞다. ARTICLE_CONTENT의 ID는 식별자이기는 하지만 이 식별자를 사용하는 이유는 ARTICLE 테이블의 데이터와 연결하기 위함이지 ARTICLE_CONTENT를 위한 별도 식별자가 필요하기 때문은 아니다. 즉, 이는 게시글의 특정 프로퍼티를 별도 테이블에 보관한 것으로 접근해야 한다.

아…그 동안 엔티티를 생각없이 무분별하게 남용해왔다는 것을 느꼈다. 여지껏 Article, ArticleContent와 비슷한 상황을 자주 경험하곤 했는데 그 때마다 1대1 연관관계를 맺어서 데이터를 조회해왔던 것이 생각이 났다. 이 책에서 Aggregate, Domain 등에 대해서 얘기하고 있는데 정작 나는 이런 개념들을 모른채 그저 생각없이 JPA를 써왔던 것 같다. ArticleContent를 밸류로 인식하기 위해서는 @Embaddable 대신 @SecondaryTable를 사용하는 것으로 책에는 설명을 하고 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import javax.persistence.*;
@Entity
@Table(name = "article")
@SecondaryTable(
name = "article_content",
pkJoinColumns = @PrimaryKeyJoinColumn(name = "id")
)
public class Article {
@Id
private Long id;
private String title;
@AttributeOverrides({
@AttributeOverride(name = "content", column = @Column(table = "article_content")),
@AttributeOverride(name = "contentType", column = @Column(table = "article_content"))
})
private ArticleContent content;
}


1
2
// @SecondaryTable로 매핑된 article_content 테이블을 조인
Article article = entityManager.find(Article.class, 1L);

여기서 굳이 @SecondaryTable@AttributeOverrides와 같은 어노테이션을 소개하려고 이 글을 쓰려했던 것은 아니다. 엔티티와 밸류를 어떻게 취급하느냐에 대해 주목해야 될 것 같다. 4장에서 애그리거트에서 엔티티와 밸류를 어떻게 다뤄야 되는지에 대한 주옥같은 방법과 설명들이 있는데 그동안 JPA를 생각없이 썼던 나에겐 굉장한 충격이었다. 책을 좀 더 읽고 애그리거트와 엔티티를 어떻게 나눌지 고민하면서 코딩을 해야겠다.

Tags: JPA DDD 나만의_책속_한줄