catsridingCATSRIDING|OCEANWAVES
Dev

Querydsl 조회 결과 Map<K, V> 타입으로 매핑하기

jynn@catsriding.com
Dec 04, 2023
Published byJynn
999
Querydsl 조회 결과 Map<K, V> 타입으로 매핑하기

Aggregate Results as Map with Querydsl

Querydsl을 활용하여 데이터베이스에서 데이터셋을 가져올 때 Map<K, V> 타입으로 결과를 가공하는 방법에 대해 살펴봅니다.

Working with ResultTransformer

Querydsl에서 제공하는 ResultTransformer 인터페이스를 활용하면 조회 결과를 Map<K, V>으로 전환할 수 있습니다.

MemberRepositoryImpl.java
@Override  
public Map<String, List<Member>> fetch() {  
    return queryFactory  
            .from(member)  
            .innerJoin(member.team, team).fetchJoin()  
            .transform(groupBy(team.name).as(list(member)));  
}
  • transform(groupBy()): 쿼리 조회 결과에서 team.name 값을 Key로, 그리고 해당 team에 소속된 member 리스트를 Value로 전환합니다.

참고로, 현재 Spring Boot 3.x 버전에서 transform()을 사용하면 NoSuchMethodError 예외가 발생합니다.

Caused by: java.lang.NoSuchMethodError: 'java.lang.Object org.hibernate.ScrollableResults.get(int)'

EntityManager를 기반으로 JPQLTemplates이 자동으로 설정돼야 하는데 이 과정에서 문제가 발생한 것입니다. 최신 Hibernate 버전과의 호환성 문제로 짐작되며 해당 이슈는 Querydsl GitHub Issues에 Open된 상태입니다.

현재 제시된 해결 방법은 JPAQueryFactory 인스턴스의 JPQLTemplatesDEFAULT로 직접 지정하는 것입니다.

QuerydslConfig.java
@PersistenceContext  
private EntityManager entityManager;  
  
@Bean  
public JPAQueryFactory jpaQueryFactory() {  
    return new JPAQueryFactory(JPQLTemplates.DEFAULT, entityManager);  
}

Querydsl의 tranform()도 결국엔 메모리 위에서 동작하는 것이기 때문에, 상황에 따라 Querydsl을 통한 데이터 조회는 List<T> 타입으로 가져온 다음 Java Stream API를 통해 Map<K, V>으로 분류하는 것이 제어 및 역할 분리에 용이할 수도 있습니다.

  • Spring
  • JPA
  • Querydsl