spring数据redis java.lang.ClassCastException
在我的测试项目中,我用SpringDataRedis和jedis构建了我的缓存系统。RedisTemplate的valueSerializer是GenericJackson2JSONRedisializer。但这里有一个问题,当我从java.lang.Long类型的缓存中选择一个列表时,有一个java.lang.ClassCastException:java.lang.Integer不能转换为java.lang.Long。任何人都知道原因,这让我困惑了很久 Redis配置详细信息如下:spring数据redis java.lang.ClassCastException,java,redis,spring-data,jedis,Java,Redis,Spring Data,Jedis,在我的测试项目中,我用SpringDataRedis和jedis构建了我的缓存系统。RedisTemplate的valueSerializer是GenericJackson2JSONRedisializer。但这里有一个问题,当我从java.lang.Long类型的缓存中选择一个列表时,有一个java.lang.ClassCastException:java.lang.Integer不能转换为java.lang.Long。任何人都知道原因,这让我困惑了很久 Redis配置详细信息如下: <
<bean id="objRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory" />
<property name="keySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean
class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
</bean>
public List<Long> findByProductId(Long productId) {
String key = ThemeRedisKeyGenerator.genProductThemeKey(productId);
List<Long> themeIdList = redisService.range(key, Long.class);
if (themeIdList == null) {
themeIdList = themeProductMapper
.selectThemeIdByProductId(productId);
if (!redisService.containKey(key)) {
redisService.rightPush(key,
ThemeRedisKeyGenerator.PRODUCT_THEME_KEY_EXPIRE_HOURS,
TimeUnit.HOURS, themeIdList.toArray());
}
}
return themeIdList;
}
public <T> List<T> range(String key, Class<T> clazz) {
return range(key, 0L, -1L, clazz);
}
public <T> List<T> range(String key, Long start, Long end, Class<T> clazz) {
if (StringUtil.isEmpty(key) || !objRedisTemplate.hasKey(key)) {
return null;
}
if (start < 0) {
start = 0L;
}
List<T> list = (List<T>) (objRedisTemplate.opsForList().range(key,
start, end));
if(list == null) {
list = new ArrayList<T>();
}
return list;
}
代码详情如下:
<bean id="objRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory" />
<property name="keySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean
class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
</bean>
public List<Long> findByProductId(Long productId) {
String key = ThemeRedisKeyGenerator.genProductThemeKey(productId);
List<Long> themeIdList = redisService.range(key, Long.class);
if (themeIdList == null) {
themeIdList = themeProductMapper
.selectThemeIdByProductId(productId);
if (!redisService.containKey(key)) {
redisService.rightPush(key,
ThemeRedisKeyGenerator.PRODUCT_THEME_KEY_EXPIRE_HOURS,
TimeUnit.HOURS, themeIdList.toArray());
}
}
return themeIdList;
}
public <T> List<T> range(String key, Class<T> clazz) {
return range(key, 0L, -1L, clazz);
}
public <T> List<T> range(String key, Long start, Long end, Class<T> clazz) {
if (StringUtil.isEmpty(key) || !objRedisTemplate.hasKey(key)) {
return null;
}
if (start < 0) {
start = 0L;
}
List<T> list = (List<T>) (objRedisTemplate.opsForList().range(key,
start, end));
if(list == null) {
list = new ArrayList<T>();
}
return list;
}
而redis的服务方式如下:
<bean id="objRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory" />
<property name="keySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean
class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
</bean>
public List<Long> findByProductId(Long productId) {
String key = ThemeRedisKeyGenerator.genProductThemeKey(productId);
List<Long> themeIdList = redisService.range(key, Long.class);
if (themeIdList == null) {
themeIdList = themeProductMapper
.selectThemeIdByProductId(productId);
if (!redisService.containKey(key)) {
redisService.rightPush(key,
ThemeRedisKeyGenerator.PRODUCT_THEME_KEY_EXPIRE_HOURS,
TimeUnit.HOURS, themeIdList.toArray());
}
}
return themeIdList;
}
public <T> List<T> range(String key, Class<T> clazz) {
return range(key, 0L, -1L, clazz);
}
public <T> List<T> range(String key, Long start, Long end, Class<T> clazz) {
if (StringUtil.isEmpty(key) || !objRedisTemplate.hasKey(key)) {
return null;
}
if (start < 0) {
start = 0L;
}
List<T> list = (List<T>) (objRedisTemplate.opsForList().range(key,
start, end));
if(list == null) {
list = new ArrayList<T>();
}
return list;
}
简言之
默认情况下,当数字小于231-1时,Jackson返回int
解释
JSON的数据类型数量有限。也没有附加类型信息:
{
"number": 42
}
42最初可以是短、int或long,但您无法从JSON中分辨出来。如果数字小于Integer.MAX\u int,则默认设置为使用int
您有多个选项来解决此问题:
使用数字作为返回数据的接口
通过提供已配置的ObjectMapper来配置GenericJackson2JsonRedisSerializer
使用使用类型详细信息的其他序列化程序,如JdkSerializationRedisSerializer
您可以找到有关JSON反序列化的更多详细信息。简而言之
默认情况下,当数字小于231-1时,Jackson返回int
解释
JSON的数据类型数量有限。也没有附加类型信息:
{
"number": 42
}
42最初可以是短、int或long,但您无法从JSON中分辨出来。如果数字小于Integer.MAX\u int,则默认设置为使用int
您有多个选项来解决此问题:
使用数字作为返回数据的接口
通过提供已配置的ObjectMapper来配置GenericJackson2JsonRedisSerializer
使用使用类型详细信息的其他序列化程序,如JdkSerializationRedisSerializer
您可以找到有关JSON反序列化的更多详细信息。因为数据来自数据库big int,所以无法使用1st。有时候,我需要检查redis服务器上的数据,如果我使用Jdk,redis中的结果是没有意义的。我不太明白第二个建议,有没有样本?数字是Long、Integer等的超级类型。快速变量是List themeIdList=redisService.rangekey,Number.class;列表结果=新的ArrayList;对于编号n:themeIdList result.addn.longValue;哦,那是个好主意。我试试看。谢谢此外,我发现当数字大于Integer.MAX_INT时,该值将转换为biginger而不是Long。非常感谢,你让我跳出了思维定势。这对我很有帮助:ObjectMapper ObjectMapper=new ObjectMapper;objectMapper.enableDeserializationFeature.USE_LONG_FOR_int;GenericJackson2JsonRedisSerializer GenericJackson2JsonRedisSerializer=新的GenericJackson2JsonRedisSerializerobjectMapper;RedisCacheConfiguration RedisCacheConfiguration=RedisCacheConfiguration.defaultCacheConfig.serializeValuesWithRedisSerializationContext.SerializationPair.fromSerializergenericJackson2JsonRedisSerializer;因为数据来自大整数数据库,所以第1个不可用。有时候,我需要检查redis服务器上的数据,如果我使用Jdk,redis中的结果是没有意义的。我不太明白第二个建议,有没有样本?数字是Long、Integer等的超级类型。快速变量是List themeIdList=redisService.rangekey,Number.class;列表结果=新的ArrayList;对于编号n:themeIdList result.addn.longValue;哦,那是个好主意。我试试看。谢谢此外,我发现当数字大于Integer.MAX_INT时,该值将转换为biginger而不是Long。非常感谢,你让我跳出了思维定势。这对我很有帮助:ObjectMapper ObjectMapper=new ObjectMapper;objectMapper.enableDeserializationFeature.USE_LONG_FOR_int;GenericJackson2JsonRedisSerializer GenericJackson2JsonRedisSerializer=新的GenericJackson2JsonRedisSerializerobjectMapper;RedisCacheConfiguration RedisCacheConfiguration=RedisCacheConfiguration.defaultCacheConfig.serializeValuesWithRedisSerializationContext.SerializationPair.fromSerializergenericJackson2JsonRedisSerializer;