개발지식/Backend Engineering

🌿 Spring Data JPA – 반환 타입 정리

우루쾅 2025. 11. 13. 08:17
728x90
반응형
SMALL

JPA를 사용하다 보면 같은 조건으로 조회하는데도 반환 타입에 따라 동작 방식이 달라지는 경우가 있습니다.
특히 List, 단일 엔티티 반환(Member), 그리고 Optional<Member> 는 반환 결과가 완전히 다르기 때문에 정확히 이해하고 사용하는 것이 중요합니다.

이번 글에서는 반환 타입의 차이를 코드와 함께 정리해보겠습니다.


✔️ 1. 테스트 코드로 살펴보는 반환 결과

@Test
public void returnType(){
    Member m1 = new Member("AAA", 10);
    Member m2 = new Member("AAA", 20);
    memberRepository.save(m1);
    memberRepository.save(m2);

    List<Member> aaa = memberRepository.findListByUsername("AAA");
    Member bbb = memberRepository.findMemberByUsername("BBB");
    System.out.println("bbb : "+bbb);

    Optional<Member> ccc = memberRepository.findOptionalByUsername("AAA");
    System.out.println("ccc : "+ccc);

    List<Member> ddd = memberRepository.findListByUsername("asdf");
    System.out.println("ddd : "+ddd.size());

    Member eee = memberRepository.findMemberByUsername("asdf");
    System.out.println("eee : "+eee);

    Optional<Member> fff = memberRepository.findOptionalByUsername("asdf");
    System.out.println("fff : "+fff);
}
 

그리고 Repository 인터페이스는 다음과 같습니다.

 
List<Member> findListByUsername(String username);

Member findMemberByUsername(String username);

Optional<Member> findOptionalByUsername(String username);
 

각 타입의 차이를 하나씩 살펴보겠습니다.


✔️ 2. List<Member> — 결과가 없어도 null을 반환하지 않는다

 
List<Member> list = memberRepository.findListByUsername("asdf");
  • 조회 결과가 없으면 null 이 아닌 빈 리스트([])를 반환
  • size() = 0
  • NPE 걱정을 하지 않아도 됨 → 가장 안전한 방식

특징 요약

상황 반환값
결과 없음 []
결과 여러 개 [Member, Member, ...]

JPA는 컬렉션 타입을 반환할 때 절대 null을 반환하지 않습니다.


✔️ 3. Member — 단일 엔티티 반환, 결과 없으면 null

 
 
Member member = memberRepository.findMemberByUsername("asdf");
  • 조회 결과가 없으면 null 반환
  • 조회 결과가 2개 이상이면 NonUniqueResultException 발생

특징 요약

상황 반환값
결과 없음 null
결과 1개 Member
결과 여러 개 ❌ 예외 발생

단일 조회에서는 사용하는 순간 항상 null 체크가 필요합니다.


✔️ 4. Optional<Member> — 결과 없으면 Optional.empty

 
Optional<Member> member = memberRepository.findOptionalByUsername("asdf");
  • 결과가 없으면 Optional.empty
  • 단일 데이터 조회를 안전하게 감싸는 방식
  • 단일 결과가 2개 이상이면 역시 예외 발생 (NonUniqueResultException)

특징 요약

상황 반환값
결과 없음 Optional.empty
결과 1개 Optional<Member>
결과 여러 개 ❌ 예외 발생

최근에는 단일 조회 시 Optional을 기본으로 쓰는 것이 안전한 패턴입니다.


✔️ 5. 반환 타입 비교 정리

반환 타입 결과 없음 결과 하나 결과 여러 개 비고
List<T> 빈 리스트([]) 리스트 리스트 가장 안전
T null 엔티티 ❌ NonUniqueResultException null 체크 필요
Optional<T> Optional.empty Optional.of(entity) ❌ NonUniqueResultException 추천 방식

✔️ 6. 실제 추천 패턴

🔹 컬렉션 조회

무조건 List

List<Member> members = repo.findListByUsername("AAA");

🔹 단건 조회

→ Optional 사용 권장

Optional<Member> member = repo.findOptionalByUsername("AAA");

🔹 단건 + 최적화된 비즈니스 규칙이 있는 경우

null 허용 가능하면 단일 객체 반환도 OK

Member member = repo.findMemberByUsername("AAA");

 

하지만 예외 상황 처리를 명확히 해야 합니다.


✔️ 7. 정리

Spring Data JPA의 반환 타입은 단순한 문법 문제가 아니라 비즈니스 규칙과 오류 처리 방식에 직접적으로 영향을 줍니다.

  • "없다면 빈 리스트" → List
  • "단건 조회인데 null-safe 하게 받고 싶다" → Optional
  • "정확히 한 건이어야 한다" → 단일 엔티티 + 예외 처리

명확한 기준을 잡고 사용하면 코드 안정성이 훨씬 높아집니다!

728x90
반응형
LIST