정리정리

소소한 스프링 레디스 컨트리뷰트 이야기 본문

Spring

소소한 스프링 레디스 컨트리뷰트 이야기

wlsh 2026. 2. 9. 23:15

이슈

최근에 새로 업데이트된 Spring boot 4.0.0를 이용해 코드를 작성해보고 있었는데, Spring Redis를 사용하는 코드에서 문제가 발생하였다.

List<Object> results = stringRedisTemplate.executePipelined(
  new RedisCallback<Object>() {
    @Override
    public Object doInRedis(RedisConnection connection) throws DataAccessException {
      StringRedisConnection stringRedisConn = (StringRedisConnection) connection; // 예외 발생 부분
      ...
      return null;
    }
  }
);

해당 코드는 Spring Redis Docs의 Pipelining 부분에 예제 코드로 나와있을 만큼 간단하면서 검증이 된 코드였다.

기존의 Spring Boot 3.x 버전에서도 잘 동작하는 것을 알고 있었기 때문에 4.0으로 올라가면서 문제가 발생했을 거라는 생각이 들어 디버깅을 해봤다.

디버깅

java.lang.ClassCastException: class jdk.proxy3.$Proxy128 cannot be cast to class org.springframework.data.redis.connection.StringRedisConnection

우선 doInRedis메서드의 파라미터로 넘어온 RedisConnection을 StringRedisConnection으로 캐스팅하는 과정에서 ClassCastException이 발생했으므로 RedisConnection의 구체 클래스를 만드는 부분을 찾아봤다.

RedisTemplate의 executePipelined 메서드를 타고 들어가다보면 execute 메서드에서 RedisConnection을 전처리하는 코드를 찾을 수 있다.

우선 RedisTemplate에서는 해당 메서드에 들어가면 별다른 작업 없이 그대로 connection을 반환한다.

이때 Spring Boot 3.x 버전에서는 RedisTemplate를 상속한 StringRedisTemplate에서 차이가 발생한다.

StringRedisTemplate에서 이 메서드를 오버라이딩하여 새로운 프록시 connection을 생성하여 반환하기 때문에 위의 코드에서 StringRedisConnection으로 캐스팅이 가능했다.

그런데 이 부분이 필요없다고 판단했는지, 4.0으로 넘어오면서 해당 부분을 삭제한 커밋(3a930ce)을 찾을 수 있었다.

이 변경 때문에 RedisTemplate에서 그대로 리턴된 connection을 StringRedisConnection으로 캐스팅하는 과정에서 예외가 발생하게 되었던 것이다.

 

Docs에도 여전히 예제 코드로 캐스팅을 하는 부분이 남아있었기 때문에 이 부분을 수정하면 좋을 것 같다는 생각을 했다.

그래서 어떤 식으로 고치면 좋을지 찾아보다가 해당 커밋에서 답을 쉽게 얻을 수 있었다.

테스트코드에서도 단순히 외부에서 StringRedisConnection 프록시 객체를 만들어 사용한 부분을 보고, 예제 코드도 테스트 코드와 결이 비슷하다 생각해 동일하게 수정 후 PR을 올렸다.

결과

그 결과, 컨트리뷰터 배지와 함께 공식 문서의 예제 코드에 내 수정사항이 올라가게 되었다.

정말 별거 아닌 내용이기도 하고 PR올릴 때 엄청 떨리고 무섭기도 했지만 많은 사람들이 사용하는 코드에 조금이나마 기여를 했다는 생각에 보람찼다!

 

https://github.com/spring-projects/spring-data-redis/pull/3281

 

Fix example code in Pipelining docs by wlsh44 · Pull Request #3281 · spring-projects/spring-data-redis

Issue When executing the example code from the Pipelining documentation using Spring Data Redis 4.0.0, a ClassCastException is thrown while attempting to cast RedisConnection to StringRedisConnecti...

github.com

https://docs.spring.io/spring-data/redis/reference/redis/pipelining.html

 

Pipelining :: Spring Data Redis

The Lettuce driver supports fine-grained flush control that allows to either flush commands as they appear, buffer or send them at connection close. LettuceConnectionFactory factory = // ... factory.setPipeliningFlushPolicy(PipeliningFlushPolicy.buffered(3

docs.spring.io

 

Comments