[SPRING] ⚒️ Repository에서 default와 Optional<>을 사용하는 이유는 무엇일까?

림민지·2025년 4월 1일

Today I Learn

목록 보기
38/62
post-thumbnail

🥹 발단

Todo 프로젝트를 만들면서 도대체 Optional<>은 왜쓰는거지? JPA에서는 그냥 이런식으로 써야만 하는건가? 라고 의문점이 많았다

List<Todo> findTodoListById(Long id);
    Todo findTodoById(Long id);

이렇게 DB를 조회하면 안되는걸까? 작동은 잘되는데 말이다.

근데 이 옵셔널과 디폴트의 조합이 너무나 꿀템이었던 건에 대하여...
나는 그냥 감자였던건에 대하여....

왜인지 함께 알아보자!!


⭐️ Optional<> & default

스프링에서 JPA를 사용할 때, repository는 데이터베이스와 상호작용하는 핵심 계층이다.
JpaRepositoryextend하면 다양한 기본 메서드를 제공하지만, 이를 어떻게 활용할지에 따라 코드의 안정성과 유지보수성이 달라진다!!

예제를 통해 기본적으로 구성한 방식과 에러처리를 잘할 수 있는 방법으로 개선한 방법을 알아보자

💭 기본 데이터 조회 방식

public interface TodoRepository extends JpaRepository<Todo, Long> {
    List<Todo> findTodoListById(Long id);
    Todo findTodoById(Long id);
}

기본적으로는 JpaRepository를 확장해 레포지토리를 사용하게 된다.

하지만 위의 코드처럼 사용하게 되면,,
findTodoById(Long id) 메서드는 존재하지 않는 ID를 조회하면 null을 반환한다.
null 체크를 따로 해야 하고, NullPointerException이 생길 수도 있다

☑️ Optional을 활용한 데이터 조회

하지만 이러한 오류를 Optional<>을 통해 개선할 수 있다.

public interface MemberRepository extends JpaRepository<Member, Long> {
    Optional<Member> findMemberByName(String name);
}

위 코드에서처럼 Optional<Member>로 반환하면,
호출하는 쪽에서 isPresent(), orElse(), orElseThrow()등의 메서드를 활용하여 명시적으로 null 처리를 할 수 있다!

✅ default로 더 효과적인 에러처리

Optional<>과 더불어 default를 함께 사용하게 되면 레포지토리 내부에서 공통적인 예외 처리를 할 수 있다

public interface MemberRepository extends JpaRepository<Member, Long> {
    Optional<Member> findMemberByName(String name);
    
    default Member findMemberByNameOrElseThrow(String name) {
        return findMemberByName(name)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "존재하지 않는 회원입니다"));
    }
}

Optional<Member>를 반환하는 findMemberByName(String name) 메서드를 감싸 orElseThrow()를 활용해 예외를 던진다.

➡️ controller 혹은 service 계층에서 불필요한 null 체크 없이 바로 사용할 수 있게 된다!!

여러가지 예외 던지기 방법이 있지만 orElseThrow가 가장 무난하게 사용 가능하다😉


👍 Optional<> + default 조합

두 방법을 함께 사용하면 시너지가 엄청나다!

1. 코드의 간결성
default 메서드를 활용하면 예외 처리를 한 곳에서 통합적으로 관리할 수 있다.
이후 사용할 클래스(서비스 계층)에서 불필요한 null 체크 코드가 줄어들어 코드가 간결해지고 가독성도 좋아진다!!

2. null 안전성 확보
Optional<>을 사용하면 null을 직접 다루지 않아도 된다.
orElseThrow()를 통해 명시적으로 예외를 던져버릴 수 있다 크크

3. 유지보수성 향상
예외 처리를 중앙화하여 코드의 중복을 줄이고 가독성을 높일 수 있다.
새롭게 조회하는 메서드를 추가해도, 동일하게 예외처리하면 되니까 아주아주 편하게 확장 가능하다ㅏ~~~!!!!


JPA를 사용하며 가장 편리하다고 느꼈던 부분이 Repository를 다루는 부분인데, 이렇게 예외처리까지 같이 해주니 가독성이 너무너무 좋아졌다!

profile
@lim_128

0개의 댓글