Reputation: 68
In my test project, I build my cache system by spring-data-redis and jedis. And the valueSerializer
of RedisTemplate
is GenericJackson2JsonRedisSerializer
. But here is a question, when I range a list from cache of type java.lang.Long, there is an java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
. Anyone knows the reason, it confused me a long time;
Redis config detail is as below:
<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>
Code detail is as below:
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;
}
And redis service method is as below:
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;
}
Upvotes: 2
Views: 9471
Reputation: 18119
By default, Jackson returns int
when the number is smaller than 231-1
JSON is limited in the number of data types. There's also no type information attached:
{
"number": 42
}
The 42
could be originally a short
, int
or long
, but you can't tell from JSON. The default setting is to use int
if the number is smaller than Integer.MAX_INT
.
You have multiple options to fix the issue:
Number
as interface to the data which comes backGenericJackson2JsonRedisSerializer
by providing a configured ObjectMapper
JdkSerializationRedisSerializer
)You can find more details on JSON deserialization here.
Upvotes: 9