Spring 7기 프로젝트/일정관리 프로젝트
[트러블슈팅] Repository에서 예외 처리와 Optional 패턴
JuNo_12
2025. 5. 13. 16:55
문제 상황
- findById 등에서 DB에 특정 값이 없을 때,
- 직접 예외를 던지는 게 좋은지,
- 아니면 Optional로 감싸서 반환하는 게 좋은지 고민이 들었다.
두 가지 패턴
1. Repository에서 비즈니스 예외 바로 던지기
@Override
public Optional<Schedule> findById(Long id) {
try {
Schedule schedule = jdbcTemplate.queryForObject(sql, new Object[]{id}, rowMapper);
return Optional.of(schedule);
} catch (EmptyResultDataAccessException e) {
throw new ScheduleNotFoundException("해당 ID의 일정이 없습니다. ID = " + id);
}
}
단점
- Repository에서 곧장 비즈니스 레이어의 예외()를 다루게 됨 → 계층 분리가 깨질 수 있음 ScheduleNotFoundException
- 데이터를 "없음"으로 처리할 때도 무조건 예외가 발생함
2. Optional.empty()를 반환하고 Service에서 예외 처리
@Override
public Optional<Schedule> findById(Long id) {
try {
Schedule schedule = jdbcTemplate.queryForObject(sql, new Object[]{id}, rowMapper);
return Optional.of(schedule);
} catch (EmptyResultDataAccessException e) {
return Optional.empty();
}
}
// Service 계층에서
Schedule schedule = scheduleRepository.findById(id)
.orElseThrow(() -> new ScheduleNotFoundException("해당 일정 없음: ID = " + id));
장점
- Repository는 단순히 "데이터 있음/없음"만 표현
- 비즈니스적 결정(예외 발생)은 Service 계층에서 담당!
- 계층 간 책임이 명확해지고, 유연성이 높아짐
결론
- Repository에서는 Optional.empty()로 "데이터 없음"을 반환하는 게 가장 좋다!
- 비즈니스 예외 변환은 Service 계층에서 처리하자.
반환 타입이 Optional인 이유
- Optional<T>로 반환한다는 건
→ "이 데이터를 요청했을 때, 없을 수도 있음"을 명확하게 보여주기 위함 - 즉,
- 1개의 값이 나올 수도 있고
- 아무 결과도 없을 수도 있다라는 것을 반환 타입에 적극적으로 드러낸다.
- 단일 PK(id)로 조회할 때
- "해당 id의 Schedule이 DB에 없으면 어떻게 할 거야?"를 생각해야 함!
List<> vs Optional<> 어떤 차이가?
| 반환 타입 | 의미 | 관례 |
| Optional<Schedule> | "최대 1건 조회, 없을 수도 있음"을 명확히 표현 | 단건(PK) 조회 표준 |
| List<Schedule> | "결과가 0개~N개 모두 가능하다" | 복수건(조건검색 등)에서 표준 |
| (null) Schedule | 없음은 null로 표현(비권장) | 권장하지 않음 |
- 단건 조회: Optional을 주로 사용
- 복수건(검색 등): List을 주로 사용
- 단건(PK로 조회한 결과 등)인데 List를 쓰면 "왜 여러 건이 나올 수 있지?" 혼동을 줄 수 있음