작지만 꾸준한 반복

Java optional - OrElse, OrElseGet 알고쓰자 본문

트러블슈팅

Java optional - OrElse, OrElseGet 알고쓰자

iamjooon2 2023. 8. 20. 01:55

우아한테크코스 프로젝트를 진행하면서

java Optional의 orElse, orElseGet을 아주 제대로 배울 기회가 생겨 정리해본다

 

후딱 계기가 된 코드부터 살펴보자.

public String createToken(String authCode) {
        String accessToken = oAuthClient.getAccessToken(authCode);
        OAuthMemberResponse oAuthMemberResponse = oAuthClient.getMember(accessToken);

        Member member = memberRepository.findByEmail(oAuthMemberResponse.getEmail())
                .orElse(memberRepository.save(oAuthMemberResponse.toMember()));

        return jwtProvider.create(String.valueOf(member.getId()));
    }

로그인하여 토큰을 발급하는 코드다

 

간략하게 설명해보자면, 클라이언트로부터 받아온 인가코드를 바탕으로

oAuthClient 객체에게 자원서버로부터 accessToken을 받아오고,

다시 받아온 accessToken을 바탕으로 회원 정보를 얻어온다

 

받아온 회원 정보중 이메일을 바탕으로 이미 존재하는 회원인지 확인하여

존재한다면 기존 회원 정보를 가져오고, 존재하지 않는다면 새로 가입한 후

 

회원의 식별자를 바탕으로 토큰을 발급한다.

 

문제가 생겼던 부분은 기존 가입자가 다시 로그인이 안되는 것이었다.

로그인이 안되던 이유는, 데이터베이스의 이메일에 unique 조약을 위반한다는 이유....

 

 

이유는 orElse를 잘 모르고 썼던 것이었다.

 

 

orElse()의 경우, 매개변수로 T를 받아, 리턴값으로 T를 반환한다

메서드 구현을 보면, 값이 null이 아니면 값을 반환하고, 아니라면 매개변수를 반환한다.

 

나는 orElse()의 인자로 메서드를 넣어주었다.

이때, 먼저 실행한 memberRepository.findByEmail()과는 상관없이

orElse에 넣었던 메서드가 먼저 실행이 되고(매개변수가 값인지라, 값을 구하기위해 메서드가 실행됨)

여기서 email Unique 제약조건이 걸렸던 것이다.

 

그래서 어떻게 해결했냐고?

orElse() 대신 orElseGet()을 사용했다

 

public String createToken(String authCode) {
        String accessToken = oAuthClient.getAccessToken(authCode);
        OAuthMemberResponse oAuthMemberResponse = oAuthClient.getMember(accessToken);

        Member member = memberRepository.findByEmail(oAuthMemberResponse.getEmail())
                .orElseGet(() -> memberRepository.save(oAuthMemberResponse.toMember()));

        return jwtProvider.create(String.valueOf(member.getId()));
    }

 

 

orElseGet()는 orElse() 와 달리 값이 아닌 supplier(매개변수를 받지 않고 리턴값을 반환)을 인자로 받는다

값이 null이 아니면 값을 반환하고, null이면 Supplier의 get을 호출한다.

이로써, 앞선 memberRepository.findByEmail()의 결과에 따라

이후 orElseGet을 실행시킬 수 있었다.

 

Optional의 orElse와 orElseGet을 잘 알고 쓰게 된 계기가 되었다.

 

 

정리

orElse는 Optional이 값이 무엇이든, 항상 로직이 실행되고

orElseGet은 Optional의 값이 null일 때만 로직이 실행된다.

잘 알고 쓰자

 

 

참고자료

https://www.baeldung.com/java-optional-or-else-vs-or-else-get