5.2 단방향 또는 양방향 관계
휴리스틱 5: 항상 단방향 관계로 시작하세요. 필요가 생기고 관계가 어그리게이트 루트를 넘지 않을 때만 양방향 관계로 변환하세요.
예를 들어, Order
와 OrderLine
간의 관계는 다음과 같이 단방향으로 시작할 수 있습니다:
@Entity
public class Order {
@Id
private Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderLine> orderLines = new ArrayList<>();
// other fields, getters and setters
}
@Entity
public class OrderLine {
@Id
private Long id;
private int quantity;
// other fields, getters and setters
}
5.3 지연 또는 즉시 로딩
휴리스틱 6: 어그리게이트 루트에서 모든 자식 관계를 지연 로딩으로 시작하세요. 관련 엔티티가 항상 필요한 경우에만 즉시 로딩으로 변환하세요.
@Entity
public class Order {
@Id
private Long id;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderLine> orderLines = new ArrayList<>();
// other fields, getters and setters
}
휴리스틱 7: 다른 어그리게이트 루트와의 관계가 있다면 절대 즉시 로딩을 사용하지 마세요.
@Entity
public class Product {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
private ProductCategory category;
// other fields, getters and setters
}
5.4 연쇄 작업(Cascade) 설정
휴리스틱 8: 어그리게이트 루트가 아닌 모든 엔티티에 대해 연쇄 작업을 설정하세요. 연관된 어그리게이트 엔티티에 대해서는 연쇄 작업을 설정하지 마세요.
@Entity
public class Order {
@Id
private Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderLine> orderLines = new ArrayList<>();
private Long customerId; // 다른 어그리게이트 루트에 대해서는 cascade 설정 없음
// other fields, getters and setters
}
6. 결론
이 교육 자료에서는 도메인 주도 설계 개념을 JPA/Hibernate 관계 설계에 적용하는 방법에 대해 설명했습니다. 다음은 8가지 휴리스틱을 요약한 것입니다:
- Spring Repository는 어그리게이트 루트 엔티티에 대해서만 정의되어야 합니다.
- 어그리게이트 내에서는
@OneToOne
또는 일부 @ManyToOne
대신 Value 객체 사용을 고려하세요.
- 어그리게이트 루트 간의 관계 매핑은 피하고, 외래 키를 그대로 매핑하세요.
- 다른 어그리게이트 루트와의 관계 매핑은 관계가 유한할 때만 허용하세요.
- 항상 단방향 관계로 시작하세요. 필요가 생기고 관계가 어그리게이트 루트를 넘지 않을 때만 양방향 관계로 변환하세요.
- 어그리게이트 루트에서 모든 자식 관계를 지연 로딩으로 시작하세요. 관련 엔티티가 항상 필요한 경우에만 즉시 로딩으로 변환하세요.
- 다른 어그리게이트 루트와의 관계가 있다면 절대 즉시 로딩을 사용하지 마세요.
- 어그리게이트 루트가 아닌 모든 엔티티에 대해 연쇄 작업을 설정하세요. 연관된 어그리게이트 엔티티에 대해서는 연쇄 작업을 설정하지 마세요.
이러한 휴리스틱을 따르면 JPA/Hibernate를 사용할 때 발생할 수 있는 많은 문제들을 예방하고 더 효율적인 데이터베이스 설계를 할 수 있습니다
*역자 comment : 지연로딩 부분은 동일 바운디드 컨텍스트 내에서는 허용 가능함
원문 참조 : Applying Domain-Driven Design Principles for JPA/Hibernate Mappings Best Practices