Spring/SpringDataJPA

반환 타입

느리지만 꾸준하게 2022. 4. 17. 18:23

스프링 데이터 JPA에는 다양한 반환타입이 존재한다.

 

MemberRepository Interface에 아래와 같이 3개의 반환타입을 만들 수가 있다.

List<Member> findListByUsername(String username); // 컬렉션
Member findMemberByUsername(String username); // 단건
Optional<Member> findoptionalByUsername(String username); // 단건 Optional

 

 

MemberRepositoryTest

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

        List<Member> result = memberRepository.findListByUsername("AAA");

    }
// run 실행결과

select
        member0_.member_id as member_i1_0_,
        member0_.age as age2_0_,
        member0_.tema_id as tema_id4_0_,
        member0_.username as username3_0_ 
    from
        member member0_ 
    where
        member0_.username=?

 

그리고 List로 받지말고 member 하나로 받으면 아래와 같이 나타낼 수 있다.

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

//        List<Member> aaa = memberRepository.findListByUsername("AAA");
        Member findMember = memberRepository.findMemberByUsername("AAA");
        System.out.println("findMember = " + findMember);
    }
findMember = Member(id=1, username=AAA, age=10)

 

 

 

parameter를 이상하게 넣었을 때 null이 아니고 empty collection을 반환을 해준다.

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

    // parameter를 이상하게 넣었을 때
    List<Member> result = memberRepository.findListByUsername("asdfasdf");
    System.out.println("result = " + result.size());
}

 

빈 컬렉션을 제공해줄수가 있다.

result = 0

 

 

 

아래 방식은 결과가 null로 나오게 된다.

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

        Member findMember = memberRepository.findMemberByUsername("asdfasdf");
        System.out.println("findMember = " + findMember);
    }
findMember = null

 

JPA는 하나를 조회했을 때 없으면 noResultException식으로 터지고

스프링 데이터 JPA는 결과가없으면 noResultException이 터지지 않고 감싸버리고 트랙킹을 찾은 다음에 null로 반환을 한다.

package javax.persistence;

/**
 * Thrown by the persistence provider when {@link
 * Query#getSingleResult Query.getSingleResult()} or {@link
 * TypedQuery#getSingleResult TypedQuery.getSingleResult()}is executed on a query
 * and there is no result to return.  This exception will not cause
 * the current transaction, if one is active, to be marked for
 * rollback.
 * 
 * @see Query#getSingleResult()
 * @see TypedQuery#getSingleResult()
 * 
 * @since 1.0
 */
public class NoResultException extends PersistenceException {

 

 

db에 데이터가 있을지 없을지 모른다?  그러면 Optional을 그냥 넣게 되면 결과가 아래와 같아진다.

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

    Optional<Member> findMember = memberRepository.findOptionalByUsername("asdfasdf");
    System.out.println("findMember = " + findMember);
}
findMember = Optional.empty

 

 

그리고 한건 조회했는데 결과가 2이상이면 에러가 터지게 된다.

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

    Optional<Member> findMember = memberRepository.findOptionalByUsername("AAA");
    System.out.println("findMember = " + findMember);
}
org.springframework.dao.IncorrectResultSizeDataAccessException: query did not return a unique result: 2; nested exception is javax.persistence.NonUniqueResultException: query did not return a unique result: 2

 

여기서 지원되는 query types들도 한번씩 확인을 해보자.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<출처 김영한: 실전! 스프링 데이터 JPA >

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-JPA-%EC%8B%A4%EC%A0%84/dashboard

 

실전! 스프링 데이터 JPA - 인프런 | 강의

스프링 데이터 JPA는 기존의 한계를 넘어 마치 마법처럼 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료할 수 있습니다. 그리고 반복 개발해온 기본 CRUD 기능도 모두 제공합니다.

www.inflearn.com