강의

멘토링

로드맵

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

JHL님의 프로필 이미지
JHL

작성한 질문수

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

주문 조회 V3: 엔티티를 DTO로 변환 - 페치 조인 최적화

Distinct 사용 전 결과에 대한 의문

작성

·

6

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예

[질문 내용]

    {
        "orderId": 4,
        "name": "userA",
        "orderDate": "2025-09-24T02:20:27.580803",
        "orderStatus": "ORDER",
        "address": {
            "city": "서울",
            "street": "1",
            "zipcode": "1111"
        },
        "orderItems": [
            {
                "itemName": "JPA1 BOOK",
                "orderPrice": 10000,
                "count": 1
            },
            {
                "itemName": "JPA2 BOOK",
                "orderPrice": 20000,
                "count": 2
            }
        ]
    },
    {
        "orderId": 4,
        "name": "userA",
        "orderDate": "2025-09-24T02:20:27.580803",
        "orderStatus": "ORDER",
        "address": {
            "city": "서울",
            "street": "1",
            "zipcode": "1111"
        },
        "orderItems": [
            {
                "itemName": "JPA1 BOOK",
                "orderPrice": 10000,
                "count": 1
            },
            {
                "itemName": "JPA2 BOOK",
                "orderPrice": 20000,
                "count": 2
            }
        ]
    }

Distinct 사용 전 결과는 위와 같이 한 주문에 대해서 두 개의 결과가 나오는건 이해했습니다. 하지만 둘다 OrderItem 배열에 2개의 값이 각각 들어가있습니다.

제 생각으로는 한쪽에는
JPA1 BOOK만,

다른 한쪽에는
JPA2 BOOK만 들어있어야하지 않나? 생각이 드네요.

실제 DB에서의 결과와 동일해야하는거 아닌가요?

즉, DB에서의 결과 처럼 아래와 같이 반환되어야 맞지 않나요?

    {
        "orderId": 4,
        "name": "userA",
        "orderDate": "2025-09-24T02:20:27.580803",
        "orderStatus": "ORDER",
        "address": {
            "city": "서울",
            "street": "1",
            "zipcode": "1111"
        },
        "orderItems": [
            {
                "itemName": "JPA1 BOOK",
                "orderPrice": 10000,
                "count": 1
            }
        ]
    },
    {
        "orderId": 4,
        "name": "userA",
        "orderDate": "2025-09-24T02:20:27.580803",
        "orderStatus": "ORDER",
        "address": {
            "city": "서울",
            "street": "1",
            "zipcode": "1111"
        },
        "orderItems": [
            {
                "itemName": "JPA2 BOOK",
                "orderPrice": 20000,
                "count": 2
            }
        ]
    }

답변 1

0

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

주어진 상황은 JPA에서 페치 조인을 사용할 때 자주 마주하는 이해할 수 있는 의문입니다. JPA에서는 엔티티와 관련된 컬렉션 데이터를 패치 조인 방식으로 가져올 때, 데이터 중복이 발생하는 모습을 보실 수 있습니다. 이는 SQL 쿼리 실행 시 데이터베이스에서 같은 orderId 값을 가진 행이 여러 건 있는 것을 JPA가 리스트에 넣어줄 때 발생하는 현상입니다.

질문 주신 내용대로라면, 각각의 OrderItem이 하나의 Order와 연결되어있는 것처럼 보입니다. JPA의 엔티티 매핑과 패치 조인에서는 중복된 Order 객체를 실제 두 개가 아닌 하나의 객체로 매핑하여 컬렉션 안에 중복된 OrderItem이 쌓이지 않도록 관리하는 방식입니다. 이런 처리 덕분에 최종적으로 반환되는 결과에서는 원하시는 방식으로 OrderId에 대한 한 개의 Order를 갖고, 그 안에 여러 OrderItem이 포함된 형태로 나타납니다.

만약 이러한 최종 결과가 예상과 다르다면, 다음과 같은 측면을 체크해 보세요:
1. 데이터베이스 설정 및 조회 방식: 도출된 데이터베이스 쿼리가 의도한 바와 일치하는지, 특정 조건으로 인해 중복된 결과를 발생시키는지 확인해야 합니다.
2. 페치 전략: 엔티티 간의 관계를 적절히 관리하고 있는지 및 지연 로딩 설정에 오차가 없는지 확인합니다.

더불어 아래의 링크들도 참고해 보시면 많은 도움이 됩니다:

  1. Spring Boot 3.x 와 관련된 distinct 처리 방식의 변화
  2. fetch join 4개만 나오는건 알겠는데 json에서는 다른이유
  3. 쿼리가 4개 나온다고 하는데, 2개만 나옵니다

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

JHL님의 프로필 이미지
JHL

작성한 질문수

질문하기