Hchanghyeon / dev-troubleshooting

개발하며 마주쳤던 크고 작은 문제들과 고민들
1 stars 0 forks source link

[Exception] Fetch 조인시 발생하는 MultipleBagFetchException 트러블 슈팅 #1

Closed Hchanghyeon closed 11 months ago

Hchanghyeon commented 11 months ago

문제 상황

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Game extends BaseEntity {

   // 생략

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "host_id")
    private Member host;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "address_depth1_id")
    private AddressDepth1 addressDepth1;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "address_depth2_id")
    private AddressDepth2 addressDepth2;

    @Embedded // @OneToMany
    private GamePositions gamePositions = new GamePositions();

    @Embedded // @OneToMany
    private GameMembers gameMembers = new GameMembers();

   // 생략

}

Game Entity에서 Lazy로 되어있는 컬럼들로 인하여 N+1 문제가 발생하여 해결하기 위해 Fetch 조인을 아래와 같이 설정하여 조회했습니다.

    public List<Game> findGamesWithInDistance(
            final Double latitude,
            final Double longitude,
            final Double distance
    ) {
        final String pointWKT = String.format("POINT(%s %s)", latitude, longitude);

        return jpaQueryFactory
                .selectFrom(game)
                .where(isWithInDistance(pointWKT, distance))
                .orderBy(getOrderByDistance(pointWKT))
                .join(game.host).fetchJoin()
                .join(game.addressDepth1).fetchJoin()
                .join(game.addressDepth2).fetchJoin()
                .leftJoin(game.gamePositions.gamePositions).fetchJoin()
                .leftJoin(game.gameMembers.gameMembers).fetchJoin()
                .fetch();
    }

문제 발생

위 메서드가 실행되면 아래와 같이 MultipleBagFetchException이 발생

Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
Hchanghyeon commented 11 months ago

해결 : [예외] Fetch 조인시 발생하는 MultipleBagFetchException 트러블 슈팅