스프링 - Redis CacheManager ClassCastException 해결하기
작성 일자 : 2024년 12월 07일
Cacheable 어노테이션
스프링에서는 @Cacheable
어노테이션을 사용하여 아래의 예시와 같이 메서드의 리턴 값을 캐싱할 수 있습니다.
@Cacheable(value = "latest-post", key = "#root.methodName")
public List<Post> getLatestPosts() {
List<Post> posts = postRepository.findAllByOrderByCreatedAtDesc();
return posts;
}
Redis를 캐시 스토어로 사용할 때, cacheName이 latest-post
인 캐시 하나만 사용하는 경우에는 문제가 발생하지 않지만, 여러 개의 캐시를 사용하는 경우에 갑자기 아래와 같은 ClassCastException
가 발생하였습니다.
java.lang.ClassCastException: class com.github.gerrymandering.domain.post.controller.response.GetPostRankingResponseDto cannot be cast to class com.github.gerrymandering.domain.post.controller.response.GetPostRankingResponseDto
해결 방법
1. 의존성에서 Spring Boot DevTools를 제거하는 방법
build.gradle
파일에서 spring-boot-devtools
의존성을 제거합니다.
2. RedisConfig
에서 cacheManager
를 정의할 때 클래스 로더를 명시적으로 지정하는 방법
@Configuration
@EnableCaching
@RequiredArgsConstructor
public class RedisConfig {
private final ResourceLoader resourceLoader;
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration
.defaultCacheConfig(resourceLoader.getClassLoader())
.entryTtl(Duration.ofHours(1));
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.withCacheConfiguration("latest-post",
RedisCacheConfiguration
.defaultCacheConfig(resourceLoader.getClassLoader())
.entryTtl(Duration.ofMinutes(10)))
.withCacheConfiguration("ranking",
RedisCacheConfiguration
.defaultCacheConfig(resourceLoader.getClassLoader())
.entryTtl(Duration.ofHours(2)))
.build();
}
}
- 위와 같이
RedisCacheConfiguration
을 생성할 때, 역 직렬화에 사용할 클래스 로더를resourceLoader.getClassLoader()
로 지정해줍니다.
Reference
https://brunch.co.kr/@springboot/212
Spring Boot DevTools 클래스로더 이슈
- 스프링부트 관련 잡다한 기술 이야기 | "Spring Boot DevTools 클래스로더 이슈"라는 제목으로 글을 작성하였는데, 막상 글을 다 작성한 후 다시 읽어보니 너무 잡다한 내용이 되었다. 그래서, 이 글
brunch.co.kr
java.lang.ClassCastException: class … is in unnamed module of loader 'app' - spring-boot-dev-tools
쿼츠 개발 시 다음과 같은 오류를 보게 되었다. org.quartz.SchedulerException: TriggerListener 'SimpleTriggerListener' threw exception: class me.myclude.quartz.info.TimerInfo cannot be cast to class me.myclude.quartz.info.TimerInfo (me.myclu
myclude.tistory.com
같은 클래스인데 왜 ClassCastException이 발생하는걸까? Redis Cache Manager가 DevTools와 만났을 때
캐싱 했더니 ClassCastException이 발생한다. java.lang.ClassCastException: com.example.demo.User cannot be cast to com.example.demo.User ?????????????? 이해할 수 없는 에러 메시지였다. 앞뒤가 똑같은 클래스구만 왜 캐스팅
12hong.tistory.com
ClassCast Exception when using Redis and Springboot frameworks in conjunction
Frameworks undoubtedly make things a lot easier for developer’s as they enables us to focus on the business aspect of the application.
medium.com