Redis null 값 캐싱하지 않기
value 가 null 일 경우 굳이 캐싱할 필요가 없기 때문에 RedisCacheManager 선언시 아래와 같이 disableCachingNullValues() 를 포함하곤 한다.
그런데 실제로 @Cacheable 를 선언한 메소드에서 null을 리턴하는 순간 아래와 같은 에러를 마주할 수 있었다.
Avoid storing null via '@Cacheable(unless="#result == null")' or configure RedisCache to allow 'null' via RedisCacheConfiguration. |
결국 @Cacheable 어노테이션에 unless = "#result == null" 속성을 추가하라는 말인데 나는 분명 전역적으로 null 을 캐싱하지 않겠다고 했는데 왜 이런 에러가 발생하는지 궁금해졌고 몇가지 테스트를 통해 에러가 발생하는 이유를 알 수 있었다.
나는 RedisCacheManager에 disableCachingNullValues() 이 null 캐싱을 비활성화 하는 것이기 때문에 null value 가 넘어오면 그냥 캐싱을 하지 않겠구나 라고 생각했는데 RedisManager에서는 null 을 단순히 비활성화 하는데에서 끝나지 않고 Exception을 발생시켜 버린다.
때문에 정상적인 처리를 위해서는 아예 null value에 대해 캐싱 자체를 시도하지 않아야 하고 null value 에 대해 아예 캐싱 자체를 시도하지 않도록 하는 것이 @Cacheable 어노테이션에 unless = "#result == null" 속성을 정의하는 것이다.
이는 서버에서 포트를 생각하면 된다. RedisCacheManager 가 곧 서버인 셈이고 서버에서는 null 포트를 비활성화한 상태인 것이다. 그럼에도 클라이언트에서 해당 포트로 연결을 시도할 경우 access denied 에러를 리턴한다.
그런데 어차피 캐싱을 시도하는 @Cacheable 를 통해 null value 캐싱 여부를 결정하는 거라면 RedisCacheManager의 disableCachingNullValues() 설정은 필요없는 거 아닌가? 그건 또 아니다. 아예 null value 를 존재하지 않게 하려면 RedisCacheManager.disableCachingNullValues() 를 통해 null 캐싱 자체를 비활성화하고 명시적으로 예외를 발생시켜주는 것이 좋다.