본문 바로가기

CS 잡지식

JPA 스펙 - 반환 타입 List,단건,Optional<단건 엔티티>

public interface MemberReposiotry extends JpaRepository<Member,Long> {



   
    //Spring Data JPA는 다양한 반환값 타입을 제공한다.
    //1] 반환 타입 : 컬렉션
    List<Member> findListByUsernameS(String username);

    // 2] 반환 타입 : 단건
    Member findMemberByUsername(String username);

    //3] 반환 타입 : 단건 with Optional
    Optional<Member> findOptionalByUsername(String username);

 

@Test@Transactional
public void returnTypes() {

    Member member1 = new Member("member1", 10);
    Member member2 = new Member("member2", 20);
    repository.save(member1);
    repository.save(member2);

    // Spring Data JPA은 컬렉션을 반환 타입으로 지원!
    List<Member> findMembers = repository.findListByUsernameS("member1");
    //만약, "member1"이 DB에 없다면, List로 NULL이 반환이 될까??
    //->NOPE!!! [빈 컬렉션], List 같은 경우, new ArrayList<>()를 반환한다.
    // 고로 if( findMembers == null ), else... 뭐 이런 코드는 안 짜도 된다.
    // (JPA는 해당 쿼리에 대한 결과가 없어도, List에 NULL값을 반환하지 않는다는 스펙이 있다)

    // 만약 username이 UNIQUE하다면 굳이 컬렉션(List)로 받을 필요가 없다.
    Member findMember = repository.findMemberByUsername("member1");
    // 만약 username에 해당하는 Member가 없을 수도 있는 경우에는 NULL을 반환을 한다.
    //-> 순수 JPA는 NoResultException을 터트려서 버리지만,
    //Spring Data JPA는 Exception을 터트리지 않고, try-catch를 내부적으로 돌려서 null을 반환한다.

    //실제로 Excpetion을 터트리는 것이 낫냐, 아니면 null을 반환하는 것이 낫냐라는 논쟁이 있었다.
    // 그러나 JAVA 8에서부터 Optional이 나오면서 이 논쟁은 사라졌다.
    // -> 1개의 객체에 대한 조회 결과가 있을 수도, 없을 수도 있는 경우에는 [Optinal]을 사용하자!
    Optional<Member> member3 = repository.findOptionalByUsername("member3");
    //근데, 위 코드에서 만약 조회의 결과가 단건이 아니라 2개 이상이면??
    //->그때는 Optional이라도 예외가 터진다.
    // Spring Data JPA는 이때에 InCorrectResultSizeDataAccessException이라는 [Spring]에서 정의된 Excpetion으로 바꿔서 예외를 터트림.
    // 우리는 현재 Repository는 JPA로 구현을 하였지만, Mongo로 Repository를 구현할 수도 있고, 다른 방식으로 Repository를 구현할 수가 있다.
    // 그러나 Spring은 그 어떠한 방법으로 구현을 하였다고 하여도, 조회 결과가 2개이상인 것에 대해서는 모두 [InCorrectResultSizeDataAccessException]
    // 으로 반환을 한다.
    // -> 장점 : Service 계층에서 JPA_Repository를 사용하다가, MONGO_Repository로 변경을 하였을 때, [똑같은] 예외가 올라오므로
    // 예외 처리에 대한 [클라이언트 코드의 수정을 하지 않아도 된다](OCP 원칙)


}

 

스프링 데이터 JPA 메뉴얼을 보면 정말 다양한 반환 타입을 지원하는 것을 확인할 수가 있다.