一般社団法人 全国個人事業主支援協会

COLUMN コラム

  • Spring Data RedisでClassCastExceptionが発生したときの対処法

佐久間です。

個人開発で作成しているアプリで、キャッシュサーバを使用した環境に対応できるようにソースの修正を先週末あたりから進めています。

ちなみに、RedisどころかNoSQLも初めてです。

概念を理解するのに苦戦中ですが、NoSQLの長所短所が感覚的に理解できてきました。すごいぞNoSQL…!

今回はSpring Data Redisを理解していなくてClassCastExceptionが発生したのでその対処法を少しだけ。

事象

エラー

java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader ‘bootstrap’)

よくある普通のClassCastExceptionです。

 

ソース

@Service
public class CacheViewsManager {@Autowired
private StringRedisTemplate redisTemplate;

public int getCount(Integer eventId) {

HashOperations<String, String, Integer> ops = redisTemplate.opsForHash();
int count = ops.get(“views”, “eid” + eventId).intValue();

return count;
}
}

大体こんな感じです。

何が悪かったのか。
答えはStringRedisTemplateをインジェクトして使用していることですね。
StringRedisTemplateはRedisTemplate<String, String>を継承したクラスです。

 

RedisTemplate<String, Integer>じゃないのでエラーになってるっていう単純な話です。

 

ソースを修正します。

@Autowired
private RedisTemplate<String, Integer> redisTemplate;

まずはこうします。

 

これだけだとRedisTemplate<String, Integer>がDIの管理対象になっていません。

@EnableCaching」を付与したクラスに以下のような記述を追加します。

@EnableCaching
@Configuration
public class CacheConfig {@Bean
public RedisTemplate<String, Integer> integerRedisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
RedisTemplate<String, Integer> redisTemplate = new RedisTemplate<String, Integer>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
return redisTemplate;
}
}

 

これだけの話でした。

ちなみに、Integerでパラメータ化せず、Object型で抽象化させておくと一つのBeanを使い回せて便利です。

 

Spring Data Redisの記事は1年くらい前の記事でも書きっぷりが違くて参考にならないものが多いです。

私のようなRedis初心者だと理屈が分からず変なところで躓きがちなので、記事にしてみました。

 

この記事をシェアする

  • Twitterでシェア
  • Facebookでシェア
  • LINEでシェア