You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redis是否会将Long类型存储为Int?类型转换异常求助

问题分析与解决方案

核心问题解答

Redis本身不会主动将Long类型存储为Int——问题出在Jackson的反序列化逻辑上。

原因解析

你使用了GenericJackson2JsonRedisSerializer作为值序列化器,这个序列化器的特性是:当反序列化JSON数值时,如果数值落在Java Integer的取值范围内(-2147483648 到 2147483647),Jackson会自动将其解析为Integer对象,而非你期望的Long。但你的RedisTemplate泛型声明为RedisTemplate<String, Long>,调用get()方法时框架会尝试将实际的Integer对象强转为Long,直接触发ClassCastException。

解决方案

提供三种可行的解决方式,按需选择:

1. 强制指定Long类型的序列化器

替换GenericJackson2JsonRedisSerializer为Jackson2JsonRedisSerializer并明确指定类型,让Jackson始终按Long类型序列化/反序列化:

@Bean
fun numericRedisTemplate(redisConnectionFactory: LettuceConnectionFactory): RedisTemplate<String, Long> {
    val template = RedisTemplate<String, Long>()

    template.connectionFactory = redisConnectionFactory
    template.keySerializer = StringRedisSerializer(Charsets.UTF_8)
    // 明确指定Long类型的序列化器
    template.valueSerializer = Jackson2JsonRedisSerializer(Long::class.java)
    template.hashKeySerializer = StringRedisSerializer(Charsets.UTF_8)
    template.hashValueSerializer = Jackson2JsonRedisSerializer(Long::class.java)

    return template
}

2. 显式转换数值类型

在获取值时主动转换类型,避免直接强转(Kotlin的扩展函数支持Integer和Long都调用toLong()):

fun getBalance(accountNumber: String): Long {
    val value = numericRedisTemplate.opsForValue().get(accountNumber)
    return value?.toLong() ?: -1L
}

3. 启用Jackson类型信息存储

配置GenericJackson2JsonRedisSerializer保存类型元信息,让Jackson反序列化时能识别原始类型:

@Bean
fun numericRedisTemplate(redisConnectionFactory: LettuceConnectionFactory): RedisTemplate<String, Long> {
    val template = RedisTemplate<String, Long>()
    // 配置带类型信息的序列化器
    val serializer = GenericJackson2JsonRedisSerializer().apply {
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
    }

    template.connectionFactory = redisConnectionFactory
    template.keySerializer = StringRedisSerializer(Charsets.UTF_8)
    template.valueSerializer = serializer
    template.hashKeySerializer = StringRedisSerializer(Charsets.UTF_8)
    template.hashValueSerializer = serializer

    return template
}

这种方式会在Redis存储的JSON中添加@class字段标记原始类型,确保反序列化时不会自动转换为Integer。


内容的提问来源于stack exchange,提问作者박수민

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:05:59