Notice
Recent Posts
Recent Comments
Link
Welcome! Everything is fine.
queryForObject() vs query() 본문
728x90
예외 처리를 구현하는 도중, 원하는 곳에서 예외가 발생하지 않고 엉뚱한 곳에서 발생해서 그 원인을 찾아보았다.
일정을 수정하는 부분 중 findScheduleByIdWithPassword()에서 내가 설정한 ScheduleNotFoundException이 아니라 EmptyResultDataAccessException이 났다.
@Transactional
@Override
public ScheduleResponseDto updateSchedule(Long scheduleId, ScheduleRequestDto dto) {
Schedule current = scheduleRepository.findScheduleByIdWithPassword(scheduleId);
if (current == null) {
throw new ScheduleNotFoundException("수정할 일정이 존재하지 않습니다.");
}
// 중략..
}
해당 메서드가 구현되어있는 Repository로 가서 살펴보니, 다음과 같이 queryForObject()를 사용하고 있는 것이 문제였다. queryForObject()는 결과가 없으면 null을 반환하는 게 아니라 예외를 던지기 때문에, Service에서 null 체크를 할 수 없던 것이었다!
@Override
public Schedule findScheduleByIdWithPassword(Long scheduleId) {
return jdbcTemplate.queryForObject(
"SELECT * FROM schedules WHERE scheduleId = ?",
scheduleWithPasswordRowMapper(),
scheduleId
);
}
따라서 queryForObject() 대신 query()를 사용하여 예외를 발생시키지 않고, 결과가 없으면 null을 반환하도록 수정했다. 그리고 Service에서 null 체크 후 사용자 정의 예외인 ScheduleNotFoundException을 던지는 것에 성공했다.
@Override
public Schedule findScheduleByIdWithPassword(Long scheduleId) {
String query = "SELECT * FROM schedules WHERE scheduleId = ? AND is_deleted = FALSE";
List<Schedule> schedules = jdbcTemplate.query(query, scheduleWithPasswordRowMapper(), scheduleId);
return schedules.isEmpty() ? null : schedules.get(0);
}
Postman에서도 내가 원하는 대 상태코드와 메세지가 출력되는 것을 볼 수 있다.
✔️ 정리
- queryForObject(): 단일 객체를 반환하는 메서드
- 결과가 반드시 1개일 거라고 가정할 때 사용해야 하는 메서드
- 조회된 결과가 0개면 EmptyResultDataAccessException 발생
- 조회된 결과가 2개 이상이면 IncorrectResultSizeDataAccessException 발생
- query(): 여러 개의 결과를 처리하는 메서드
- 조회된 결과가 1개 이상이면 리스트로 반환
- queryForObject()와 다르게 결과가 없을 때 예외를 던지지 않음
즉, "조회된 결과가 없을 수도 있다"면 query()를 쓰고, "반드시 1개가 나와야 한다"면 queryForObject()를 쓰자!
'TIL' 카테고리의 다른 글
INSERT 됐지만 테이블이 안보이는 문제(@Transactional) (0) | 2025.02.12 |
---|---|
Spring에서 @RequestBody를 사용할 때 주의해야 할 점 (0) | 2025.02.04 |
[TIL] 네트워크, HTTP와 HTTP의 특징 (0) | 2025.01.22 |
[TIL] 계산기 과제 해설, 와일드카드, 타입 이레이저 (0) | 2025.01.10 |
[TIL] enum 클래스에 연산자 담기, BiFunction 인터페이스 (0) | 2025.01.08 |