기록하기

EhCache - StringCacheKeyGenerator 사용 시 @Cacheable 적용 본문

Server/Spring Boot

EhCache - StringCacheKeyGenerator 사용 시 @Cacheable 적용

jjungdev 2022. 9. 18. 17:52

회사에서 프로젝트를 진행하던 중 ehcache 를 사용해야했으며 key 생성에는 StringCacheKeyGenerator 를 import 받아서 사용하고 있었다. 

 

StringCacheKeyGenerator 란, Cache 를 저장할 때 key 를 생성하는데 있어서 사용할 수 있는 방법 중 하나이다.

com.googlecode.ehcache-spring-annotations 를 import 하여 사용할 수 있으며 CacheManager 를 활용하여 cache 를 생성할 때 Bean 으로 주입받은 해당 객체를 사용하여 generateKey 메소드로 cache 를 저장할 수 있다.

 

하지만 프로젝트에서 org.springframework.boot:spring-boot-starter-cache 와 함께 사용하기 위해 @Cacheable 을 적용하자, Cache 에서 데이터를 가져오는 것이 아니라 계속 DB 에 접근하는 오류를 확인했다. 결국 StringCacheKeyGenerator 의 저장하는 방법을 이해한 뒤에 해결할 수 있었는데, 그 삽질에 대한 과정을 기록해보고자 한다.

 

(회사 프로젝트에서는 key 값이 객체였기에 keyGenerator 가 필요했었다. 하지만 예시에서는 간단하게 생성해보고자 dto 클래스의 필드값을 활용했으니 이 부분은 참고하여 봐주셨으면 좋겠다.)

 

1. @com.googlecode.ehcache.annotations.Cacheable 를 사용

@com.googlecode.ehcache.annotations.Cacheable(cacheName = "exampleCache", keyGeneratorName = "stringCacheKeyGenerator", cacheNull = false)
public Member saveCache(CacheParam param) {
    return memberRepository.findById(param.getId());
}

처음에는 위와 같이 설정을 했다.

ehcache.xml 에 대한 설정과 @EnableCaching 설정은 완료한 상태이며 이는 다른 분들의 블로그에서도 내용을 확인할 수 있기에 해당 내용은 제외하도록 하겠다.

 

처음 사용한 법에는 Cacheable 은 googlecode 의 Cacheable 을 사용하였고, 미리 설정한 ehcache.xml 파일에서의 cacheName 에 따라 캐싱이 되도록 설정을 했다. 즉, param 으로 가져오는 Member 가 캐싱이 되도록 설정을 했는데, 수동적으로 캐시를 저장한 후 확인하는 메소드에서는 캐시가 잘 저장되는 것을 확인했으나 이 메소드에서는 캐싱이 된 값에서 가져오지 않고, DB 에 접근하는 것을 확인했다.

 

블로그를 확인해 본 결과 다음의 방식으로 방법을 바꿨다.

 

2. StringCacheKeyGenerator 버리고, @org.springframework.cache.annotation.Cacheable 사용

뭔가 StringCacheKeyGenerator 이것이 문제라고 생각되어졌다. key 를 생성하는 방식을 보니, StringBuilder 를 통해 [] 를 앞뒤로 붙여주고 있었다.

그래서 처음에는 해당 키 제너레이터를 생략하고 아래와 같은 방법으로 적용을 해보았다.

@org.springframework.cache.annotation.Cacheable(cacheNames = "exampleCache", key = "#param.id", unless = "#result != null")

 

하지만 뒤이어 발생한 문제로는, 캐싱을 수동적으로 저장해주는 곳과 이 곳 @Cacheable 에서 저장되는 방법의 차이로 인해 계속적으로 오류가 발생하게 되었다.

결국 아주 간단한 방법으로 이를 해결했는데, 바로 앞뒤로 붙여주는 방법처럼 @Cacheable 에서도 앞뒤에 [] 를 붙여주는 방법으로 해결할 수 있었다. 해결하기까지 정말 여러 방법을 사용해봤는데, KeyGenerator 의 구조를 잘 이해하면 해결되는 간단한 문제였다..

 

3. 해결한 방법

@org.springframework.cache.annotation.Cacheable(cacheNames = "exampleCache", key = "'[' + #param.id + ']'", unless = "#result != null")
    public Member saveCache(CacheParam param) {
        return memberRepository.findById(param.getId());
    }

key 부분을 '[' + #param.id + ']' 로 수정을 해주자, stringCacheKeyGenerator.generateKey() 를 수행하는 메소드와도 충돌이 생기지 않았고 캐싱 역시 잘 수행되어 DB 에 접근하지 않고 빠르게 데이터를 가져오는 장점도 가져갈 수 있었다.

 

사소한 내용일 수 있겠지만 생각보다 고민을 오래한 부분이기에 블로그에 남겨본다. 

캐싱 설정 방법 등에 대해서도 추후에 추가하도록 하겠다.

 

 

참고

https://jojoldu.tistory.com/57

 

SpringBoot + Ehcache 기본 예제 및 소개

팀내 신입사원들이 입사하게 되어 간단하게나마 참고할 수 있도록 Spring Cache에 대해 샘플예제와 소개를 정리하게 되었다. 아주 간단한 예제이기도 하고, 웬만한 경력 웹 개발자분들은 다 아는

jojoldu.tistory.com