인프런 커뮤니티 질문&답변

요니님의 프로필 이미지
요니

작성한 질문수

Practical Testing: 실용적인 테스트 가이드

Business Layer 테스트 (1)

OrderResponse에 List<ProductResponse> 를 추가하는게 적절한가 에 대해 의문이 듭니다

작성

·

455

0

안녕하세요 강사님!

질문 드리기에 앞서 항상 좋은 강의 감사드립니다!

제가 강의를 수강하면서 의아한 부분이 있었는데요,

바로 OrderResponse에 List<ProductResponse> 를 추가하신 부분 입니다.

이에 따라 OrderResponse의 of() 메소드 안에서

order.getOrderProducts() 를 호출할 수 밖에 없게 되었는데요,

이때 페치조인을 하지 않는 이상 쿼리가 나가게 될 것 같습니다 (지연로딩)

저는 바로 이 측면이 개인적으로 잘못되었다고 생각하는데요,

JPA는 어떤 쿼리가 어느 타이밍에 나가는지를 파악하기 어려워서, 최대한 이 측면을 명확하게 해주는게 필요하다고 생각합니다.

그래서 저의 경우는 서비스 로직에서 사용되는 repository 메소드 들에서만 쿼리가 나가는 경우로 명확하게 제한을 해주는 편 인데요,

이런식으로 서비스 로직이 아닌(정확히는 그 안에서 사용되는 repository메소드) 다른 곳에서 지연로딩으로 인해 쿼리가 나간다면 - 어느타이밍에 어떤 쿼리가 나가는지를 코드만 보고 명확하게 파악할 수 없게 된다고 생각합니다.

그래서 결론적으로 저는 OrderResponse 안에서 order.getProducts()를 호출하여 List<ProductResponse>를 만드는게 적절하지 않다고 생각하는데요, 이부분에 대해 강사님의 생각을 말씀해주시면 감사하겠습니다!

감사합니다.

답변 2

1

박우빈님의 프로필 이미지
박우빈
지식공유자

안녕하세요, khd1692님! :)

네 맞습니다. 사실 JPA에 대한 강의가 아니다보니 구체적으로 짚고 넘어가지 않은 부분인데요.
강의에서는 객체 간 직접 참조로 Order, Product, 그리고 중간 테이블인 OrderProduct를 두었는데, 사실 질문주신 내용 등의 이유로 인해 ID 기반의 간접 참조를 더 선호하고 있습니다. ㅎㅎ

간접 참조 방식이었다면 객체 참조를 하지 못하니 자연스레 주문에 해당하는 대상 Product의 ID값을 모아 ProductRepository에서 한번 더 조회를 해서 응답을 구성했을 것입니다. ㅎㅎ
저도 강의를 기획할 때 이 부분까지 고려했으나, 이렇게 되면 테스트 강의가 아니라 JPA 강의가 될 것 같아서...ㅎㅎㅎ 이야기하지 않고 넘어간 부분이었는데 좋은 질문 주셨네요 👍

감사합니다. :)

안녕하세요 선생님

질문을 잘 이해 했는지 아리송 하여 질문 드립니다.

 

Order, Product, OrderProduct는 서비스에서

값을 다 넣었기 때문에 지연로딩이 발생 하지 않지만

만약 다른사람이 OrderResponse를 사용 한다고

가정 하였을 때

파라미터인 Order 만 조회 하여 넣게 된다면

지연 로딩이 발생 하여 어디서 지연 로딩이

발생 하게 되었는지 알 수 없으므로

dto 에서 직점 참조를 지양 해야

한다는게 맞을까요?

그렇다면 파라미터 값으로

OrderResponse of(Order order,

List<Product> products) 이렇게 받는 것이

좋은 방법 인가요?

 

0

안녕하세요, 인프런 AI 인턴이에요. OrderResponse 클래스에 List를 추가하는 것에 대해 의문이 들었고, JPA에서 쿼리가 언제 실행되는지 파악하기 어려워서 혼란스러웠다는 말씀이신가요?

JPA의 경우, FetchType.LAZY 속성을 사용하여 연관된 엔티티를 지연로딩(Lazy Loading)할 수 있습니다. OrderResponse 클래스의 List은 기본적으로 지연로딩이 적용되어 연관된 엔티티는 실제로 사용될 때 DB에서 쿼리를 실행합니다. 따라서 order.getOrderProducts()를 호출하는 시점에서 실제로 쿼리가 나가게 됩니다.

하지만, 코드상으로 어떤 타이밍에 어떤 쿼리가 실행되는지 명확하게 확인하기 어려울 수 있습니다. 이를 개선하고자 하시는 것은 옳은 접근입니다. 다만, OrderResponse 클래스에서 order.getProducts()를 호출하는 것보다는 서비스 레이어에서 필요한 데이터들을 명시적으로 가져오는 것이 더 명확하고 예측 가능한 방법일 수 있습니다.

따라서, 서비스 로직에서 사용되는 repository 메소드들에서만 쿼리가 실행되고 나머지 곳에서는 최대한 지연로딩을 피하는 것이 좋은 방법일 수 있습니다. 이를 위해 페치조인(Fetch Join)을 사용하여 연관된 엔티티를 함께 조회하는 방법을 고려해볼 수도 있습니다.

그렇지만 상황에 따라서 지연로딩을 사용하는 것이 더 효율적인 경우도 있을 수 있으니 신중하게 판단하셔야 합니다. 적절한 성능 테스트와 개발 방법에 따라서 최적의 방법을 선택하시면 될 것 같아요.

답변이 도움이 되셨길 바랍니다. 추가로 궁금한 점이 있으시면 언제든지 물어보세요. 좋은 하루 되세요!

요니님의 프로필 이미지
요니

작성한 질문수

질문하기