[Spring Boot] Query did not return a unique result: 3 results were returned 에러 해결하기

밤새·2024년 11월 21일
1

Spring Boot로 애플리케이션 개발 중 아래와 같은 에러를 만난 적이 있으신가요?

Query did not return a unique result: 3 results were returned

이 글에서는 이 오류의 원인과 해결 방법에 대해 알아보겠습니다!

발생 원인

상황 : findTopBy 를 이용하여 특정 사용자(user)와 파트너(partner) 간의 가장 최근 메시지 1개를 가져오려고 했습니다.

// repository
@Query("SELECT m FROM ChatMessage m WHERE m.user = :user AND m.partner = :partner ORDER BY m.timestamp DESC")
ChatMessage findTopByUsersOrderByTimestampDesc(@Param("user") User user, @Param("partner") User partner);
// service
Optional<ChatMessage> lastMessageOpt = chatMessageRepository.findTopByUsersOrderByTimestampDesc(user, partner);

하지만 실제 DB에는 조건을 만족하는 메시지가 여러 개 리턴되었고, JPA는 내부적으로 getSingleResult()를 호출하면서 결과가 2개 이상이면 예외를 던졌습니다.

findTopBy를 사용해도 내부적으로 getSingleResult() 호출 → row가 2개 이상이면 NonUniqueResultException 발생


해결 방법

반환 타입을 List<ChatMessage>로 변경getResultList()를 사용하도록 바꿨습니다.

수정된 부분

// service
List<ChatMessage> lastMessages = chatMessageRepository.findTopByUsersOrderByTimestampDesc(user, partner);
ChatMessage lastMessage = lastMessages.isEmpty() ? null : lastMessages.get(0);

여러 row 반환돼도 예외 없이 List로 받고, 첫 번째 row를 직접 선택하여 에러를 해결했습니다!


결론

  • Optional<ChatMessage>는 내부적으로 getSingleResult() 사용 → row 2개 이상이면 NonUniqueResultException 발생
  • List<ChatMessage>getResultList() 사용 → row 여러 개여도 예외 없이 반환
  • 따라서 반환 타입을 List로 바꾸고 첫 번째 row를 직접 선택하는 방식으로 문제 해결

같은 문제를 겪는 분께 참고가 되길 바랍니다!

profile
프로젝트를 통해 배운 개념이나 겪은 문제점들을 정리하고, 회고록을 작성하며 성장해나가는 곳입니다 😊

0개의 댓글