• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

하나의 앤티티에 일대다 매핑을 2개 이상 일 때 한꺼번에 조회하면 데이터가 뻥튀기 됩니다.

24.04.02 17:54 작성 조회수 64

0

안녕하세요.

제가 겪고 있는 문제에 관해서 질문드리고 싶습니다.
A 라는 앤티티가 B 와 C 를 패치 조인 전략을 사용해서 일대다 양방향을 하고 있는 상황입니다.

query
    .selectFrom(A)
    .leftJoin(A.B, B).fetchJoin()
    .leftJoin(A.C, C).fetchJoin()
    .where(A.id.eq(AId))
    .fetchOne()

위와 같이 B 와 C 를 모두 패치 조인해서 한꺼번에 조회하게 되면 B 의 데이터가 C 의 개수 만큼 뻥튀기 되는 상황이 발생합니다.

이를 어떻게 해결할 수 있는지 궁금합니다.

저는 각각의 앤티티를 따로 따로 조회해서 A 에 할당해준다는 방법을 떠올렸는데 이렇게 하면 A 에 setter method 를 만들어야 해서 좋은 패턴이 아니라는 생각이 들었습니다.

 

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.04.02

안녕하세요, 인프런 AI 인턴입니다.

안호성님의 문제는 일대다 관계에서 발생하는 패치 조인 시에 데이터 중복(뻥튀기) 현상에 대한 것입니다. 이러한 상황은 ORM을 사용할 때, 특히 복수의 컬렉션을 패치 조인할 때 자주 발생하는 문제입니다.

안 호성님이 직면한 경우와 직접적으로 일치하는 해결책은 아래의 링크에서 찾을 수 있습니다:

  • 일대다 페치 조인과 페이징에 대해: 이 링크에서는 일대다 관계의 페치 조인이 데이터 중복 현상을 발생시키는 이유와 이것이 애플리케이션의 메모리에 어떤 영향을 미치는지에 대해 설명하고 있습니다. 패치 조인과 데이터 중복이 일어나는 상황에 대한 이해를 돕기 위한 자료입니다.

해당 질문과 답변 내에서는, 일대다 관계에서 패치 조인을 사용할 경우 데이터 중복이 발생하는 것을 확인하고 그 현상을 이해하는 데 도움이 될 것입니다. 추가적으로, 문제 해결 방법으로 다음과 같은 접근을 고려할 수 있습니다:

  1. 따로 조회: 이 방법은 각 연관관계를 별도로 조회하고 결과를 조합하는 방식입니다. 이 방법은 SQL 쿼리 수는 증가하지만, 데이터 중복 문제를 피할 수 있습니다. 강의에서 설명하는 것처럼, 필요한 데이터를 개별적으로 조회한 후 애플리케이션 레벨에서 조합하는 것입니다.

  2. DTO 사용: 엔티티가 아닌, DTO를 직접 조회하는 방식으로 접근하는 것도 가능한 해결책 중 하나입니다. 이 방법은 패치 조인을 통한 데이터 중복 없이 필요한 데이터만 선택적으로 조회할 수 있습니다.

  3. @BatchSize 사용: 패치 조인 대신 연관관계에서 @BatchSize를 사용하여 N+1 문제를 해결할 수도 있습니다. 이 방법은 첫 쿼리 결과에 포함된 ID를 바탕으로 대량의 ID를 한 번에 조회하여 연관된 엔티티를 로드합니다.

각 방법은 상황에 따라 장단점이 있으므로, 케이스에 맞게 효율적인 방안을 선택해야 합니다. 데이터 중복 없이 효율적인 데이터 접근을 위한 최적의 방법을 찾으시길 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.