프로필 관련 테스트를 하다가
이 부분에서 계속 테스트가 실패해서 로그를 확인해봤다.
여길 보면 Long에서 longValue()메서드를 쓰면 참조타입-> 기본타입 number로 변경이 되는데
null이라서 이 메서드를 사용할 수 없다는 것이다.
그렇다. MyProfile 응답에서 위처럼 long으로 필드를 json으로 보내고 있기에
참조->기본으로 변경되는 과정에서 null이니 변환이 안 된다는 것이다.
이렇게 변경해주면 문제는 해결된다.
그런데, Point Key를 조회하는 곳마다 이렇게 변경을 해주어야 한다는 게 불편하다.
A, B, C에서 이렇게 로직을 구성했다고 해보자.
로직 변경을 했을 때
A와 B만 고치고 C는 실수로 안 고치면, 또 문제가 생기는 것이다.
기본타입과 참조타입에 대해서 한번 정리해보고
위의 불편함을 해결할 방법이 있는지도 알아보자.
이 기회에 기본타입과 참조타입에 대해서 좀 정리를 해보자.
우선, 간단하게 설명하면 기본타입은 그냥 값만 갖고 있는 것이고 참조타입은 메모리 주소를 갖는다. 그래서, 참조 타입은 값이 같아도 메모리 주소값이 다르면 다르다고 인식된다.
참조 타입은 null응 허용하고, 기본 타입이 메모리 사용과 성능 측면에서 더 유리하다.
기본적으로, 참조->기본 기본 ->참조로 오토 방싱/언박싱되는 건 성능에 영향으 줄 수 있으니 조심하자.(참고로 참조 형은 여러 메서드를 제공하는데 이게 필요한 경우에도 참조를 쓸 수 있다)
우선 반환타입을 기본형으로 변경했다.
그런데,
Null return value from advice does not match primitive return type for: public abstract long com.plaything.api.domain.repository.repo.pay.PointKeyRepository.countAvailablePointKey(java.lang.String)
org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public abstract long com.plaything.api.domain.repository.repo.pay.PointKeyRepository.countAvailablePointKey(java.lang.String)
참조타입을 기본형으로 바꿀 수 없다는(반환값이 NULL이라서) 예외가 발생했다.
그래서, COALESCE를 사용하기로 했다.
COALESCE는 인자로 주어진 컬럼들 중 NULL이 아닌 경우의 값을 리턴한다.
인자들을 하나씩 확인하면서 첫번째 인자가 NULL이 아니면 첫번째 인자의 값을 반환,
NULL이면 칼럼 2를 반환하는데 여기서도 NULL 체킹을 해서 NULL이 아니면 값을 반환한다.