트러블 슈팅/Spring Data

[트러블 슈팅] Could not create query for public abstract

jaehee1113 2025. 1. 1. 21:16

❗️문제 상황


에러메시지

Caused by: org.springframework.data.repository.query.QueryCreationException: 
Could not create query for public abstract java.util.List com.wsws.moduleinfra.
repo.feed.JpaAnswerRepository.findAllByUserIdAndVisibilityTrueWithCursor
(java.lang.String,java.time.LocalDateTime,org.springframework.data.domain.Pageable); 
Reason: Validation failed for query for method public abstract java.util.List 
com.wsws.moduleinfra.repo.feed.JpaAnswerRepository.findAllByUserIdAndVisibilityTrueWithCursor
(java.lang.String,java.time.LocalDateTime,org.springframework.data.domain.Pageable)

 

에러 코드

@Query("""
        SELECT new com.wsws.moduledomain.feed.dto.AnswerQuestionDTO(a.id, a.createdAt, q.content, a.visibility) 
        FROM AnswerEntity a join fetch a.questionEntity q 
        WHERE a.userId = :userId 
        AND a.createdAt < :answerCursor 
        ORDER BY a.createdAt DESC
        """)
List<AnswerQuestionDTO> findAllByUserIdWithCursor(String userId, LocalDateTime answerCursor, Pageable pageable);

 

💡 원인 파악 및 해결 과정


📑 원인

페치 조인 사용 시 특정 Entity가 아닌 별도의 Dto클래스를 받아오려는 경우 발생하는 문제였다.

해당 경우 예외가 발생하는 이유는 다음과 같다.

 

이유

  1. 페치 조인의 목적: 페치 조인은 연관된 엔티티를 함께 로드하기 위해 사용. JPA는 이를 통해 영속성 컨텍스트에 엔티티를 관리하고, 지연 로딩(N+1 문제)을 방지. 하지만 DTO는 영속성 컨텍스트의 관리 대상이 아니기 때문에 페치 조인과 DTO 반환을 동시에 사용할 수 없다.
  2. DTO 반환 방식의 제한: JPQL에서 DTO 반환은 new 패키지.클래스명 형태로 지정하며, 이는 Hibernate가 DTO를 생성할 때 사용할 생성자를 호출하는 방식. 이 과정에서는 영속성 컨텍스트와 무관하게 데이터만 반환.

 

💡 해결

@Query("""
        SELECT a 
        FROM AnswerEntity a join fetch a.questionEntity q 
        WHERE a.userId = :userId 
        AND a.createdAt < :answerCursor 
        ORDER BY a.createdAt DESC
        """)
List<AnswerEntity> findAllByUserIdWithCursor(String userId, LocalDateTime answerCursor, Pageable pageable);
  • 그냥 Entity형태로 반환
  • 이후 Dto로의 변환 과정은 별도로 처리해주었다.