❗️문제 상황
에러메시지
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클래스를 받아오려는 경우 발생하는 문제였다.
해당 경우 예외가 발생하는 이유는 다음과 같다.
이유
- 페치 조인의 목적: 페치 조인은 연관된 엔티티를 함께 로드하기 위해 사용. JPA는 이를 통해 영속성 컨텍스트에 엔티티를 관리하고, 지연 로딩(N+1 문제)을 방지. 하지만 DTO는 영속성 컨텍스트의 관리 대상이 아니기 때문에 페치 조인과 DTO 반환을 동시에 사용할 수 없다.
- 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로의 변환 과정은 별도로 처리해주었다.
'트러블 슈팅 > Spring Data' 카테고리의 다른 글
[트러블 슈팅] Spring Data Redis와 Spring Redis Search 동시에 사용시 발생하는 문제 (0) | 2025.01.01 |
---|---|
[Trouble-Shooting] Spring JPA @ColumnDefault 오류 (0) | 2024.04.11 |