• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

DDD 애그리거트 에서 JPA 지연로딩 전략이 궁금합니다.

21.06.16 13:50 작성 조회수 344

1

안녕하세요! 영한 선생님 

스프링 클라우드와 JPA를 사용하여 간단한 마이크로서비스 구축을 하는 연습을 하는 도중 궁금증이 생겨서 질문을 올리게 되었습니다.

예를 들면 대출 (Rental)이라는 애그리거트는 반납도서와 대출도서라는 엔티티를 연관관계로 맺고 있습니다.

대출 (1) ---- (N) 반납 도서

대출 (1) ---- (N) 대출 도서 

영속성 전이(cascade) + 고아 객체(orphanRemoval)를 통해서 대출 애그리거트 를 통해서 반납 도서와 대출 도서를 생명주기를 관리하고 있습니다.

제가 궁금한 점은

지연로딩 전략을 사용해서 컬렉션 패치 조인을 사용할 때 너비로든 깊이로든 2개 이상의 컬렉션 페치조인을 사용하면 안된다고 알고 있습니다. 

그럼 지연로딩 전략을 통해서 대출과 반납도서 대출도서를 조회해오는 방법은 어떻게 하면 좋을지 고민입니다.

대출과 반납도서를 먼저 페치조인으로 조회해오고 다음 대출에 속한 대출 도서를 조회해오면 된다고 생각하고 있습니다.

-> 대출에 속한 대출 도서를 조회할 때는 리포지토리를 통해 조회하는게 좋을까요 아니면 대출 애그리거트에서 대출 도서를 사용하는 시점에 초기화해서 사용하는게  좋을까요??

또 궁금한 점이 애그리거트 루트 패턴을 사용할 때는 애그리거트에 대한 리포지토리만 생성하고 하위 엔티티에 대한 리포지토리를 생성할 필요가 있는지 궁금합니다.

질문을 두서 없이 작성한 거 같아서 정리하자면

1. 애그리거트 루트 패턴을 사용할 때 애그리거트에서 2개의 컬렉션 (지연 로딩) 조회 전략

2. 애그리거트 루트 패턴을 사용할 때의 리포지토리 생성전략

3. 영속성 전이와 고아 객체를 통해 자식의 생명주기를 관리하고 있는데 자식리포지토리를 조회용으로 생성해도 되는지??

입니다.!

---------- 추가

상품 서비스와 주문 서비스에서 주문 가능한 상품이 여러개라고 할 때 

주문 (1) - 주문_상품 (N)   ||(서비스 분리)  상품 

으로 만들어지고 주문_상품이라는 엔티티에서 상품의 ID를 가지고 있으면 된다고 생각합니다.

만약 어떠한 주문의 주문 상품목록을 조회한다고하면  주문 서비스에서 주문_상품의 ID 리스트를 Feign-Client 같은 동기 API 호출을 통해서 상품 서비스에서 IN 쿼리로 상품들의 정보를 조회한 뒤에 응답을 받고 응답 받은 데이터를 클라이언트에게 보내주는 방법이 맞는지 궁굼합니다. 

정리하자면 

주문서비스에서 주문한 상품의 목록에 대한 정보를 클라이언트에게 보내줄 때 상품 서비스에서 상품 Id List를 IN쿼리로 조회를 해서 응답하는 것이 맞는지 입니다!

답변 1

답변을 작성해보세요.

1

안녕하세요. 황주님

이 경우 대출과 반납도서를 꼭 fetch join으로 조회하기 보다는 다 지연로딩으로 조회 하는 것도 고려가 필요합니다.

이 경우 N+1 문제를 해결해야 하니 활용2편에서 설명드린 것 처럼 default_batch_fetch_size, @BatchSize 등은 적용하는 것이 좋습니다.

추가로 질문하신 부분은 다음과 같이 답변을 드릴 수 있을 것 같아요.

너무 고민을 많이 하고 있다면, 애그리거트 루트를 너무 큰 단위로 만들었을 가능성이 높습니다.

실제 애그리거트 루트는 거의 엔티티와 1:1이 될 정도로 많이 많들어지게 됩니다.

반납 도서도 애그리거트 루트가 되어야 하는 것 아닌가?

대출 도서도 애그리거트 루트가 되어야 하는 것 아닌가?

이런 고민이 오히려 필요합니다.

원칙적으로 애그리거트 루트당 리포지토리를 두는 것이 맞습니다. 하지만 애그리거트 루트는 등록, 수정, 삭제 같은 command 비즈니스 처리에는 잘 맞지만, 최적화된 조회에는 잘 맞지 않는 경우가 많습니다. 실무에서는 조회에 대한 최적화를 위해서는 애그리거트당 리포지토리를 완전히 지키기 어려울 수 있습니다.

따라서 command에서는 애그리거트를 지키되, 조회 최적화가 필요한 부분은 별도의 QueryRepository 등을 만들어서 개발하는 유연성이 필요합니다.

추가로 질문하신 부분은 마이크로 서비스에서 주문, 상품 서비스가 분리되어 있는 경우를 말씀하시는 군요?

이때는 질문하신 것 처럼 API로 호출해도 되지만, 주문 마이크로서비스에서 상품에 대한 정보를 어느정도 가지고 있는 것이 더 효율적일 수 있습니다.

관련해서 다음 영상을 참고하시면 도움이 되실거에요.

https://www.youtube.com/watch?v=BnS6343GTkY

감사합니다.

황주환님의 프로필

황주환

질문자

2021.06.17

답변 감사하고 사랑합니다 영한선생님! MVC2편도 기다리고 있겠습니다!

네 황주님 화이팅^^!