Spring Data Redis反序列化问题:Map<Integer, int[]>属性无法反序列化
Great question! That error pops up because Spring Data Redis's default serialization has trouble handling generic Maps with primitive int[] values—especially when dealing with "setterless" properties (like your mymap field, which is initialized directly without a dedicated setter). Here are several practical fixes you can try, ordered by simplicity:
1. Switch to Integer[] instead of int[] (simplest fix)
If your business logic allows it, swapping the primitive int[] for the wrapper type Integer[] often resolves the issue instantly. Default Jackson-based serializers handle wrapper type arrays far more reliably than primitive ones, since they don't run into the same type inference hurdles during deserialization.
Just update your field definition:
Map<Integer, Integer[]> mymap = new HashMap<>();
2. Configure GenericJackson2JsonRedisSerializer with type information
The default Jackson2JsonRedisSerializer doesn't retain full type metadata, which causes problems with complex generic types like Map<Integer, int[]>. Switching to GenericJackson2JsonRedisSerializer (which includes type hints in the serialized JSON) fixes this gap.
Add this configuration class to your project:
@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); // Use GenericJackson2JsonRedisSerializer to preserve type info GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(); template.setDefaultSerializer(serializer); template.setValueSerializer(serializer); template.setHashValueSerializer(serializer); return template; } }
This tells Spring Data Redis to include type details in the serialized data, so it knows exactly how to deserialize Map<Integer, int[]> back to the correct type.
3. Custom Serializers for the int[] Type
If you can't switch to Integer[] or adjust the global serializer, you can build custom Jackson serializers and deserializers specifically for int[], then attach them to your mymap field.
First, create the serializer:
public class IntArraySerializer extends JsonSerializer<int[]> { @Override public void serialize(int[] value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeStartArray(); for (int num : value) { gen.writeNumber(num); } gen.writeEndArray(); } }
Then the deserializer:
public class IntArrayDeserializer extends JsonDeserializer<int[]> { @Override public int[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode node = p.getCodec().readTree(p); int[] arr = new int[node.size()]; for (int i = 0; i < node.size(); i++) { arr[i] = node.get(i).asInt(); } return arr; } }
Finally, annotate your field to use these custom handlers:
@JsonSerialize(using = IntArraySerializer.class) @JsonDeserialize(using = IntArrayDeserializer.class) private Map<Integer, int[]> mymap = new HashMap<>();
This gives you full control over how int[] is serialized and deserialized, bypassing Spring Data's default issues with primitive arrays.
4. Use Redis Hash Structure Directly
If you don't need to serialize the entire object at once, you can store your mymap directly as a Redis Hash (where each key in your Map becomes a field in the Redis Hash, and the int[] becomes the value). This avoids complex object serialization entirely.
Example code for storage:
// Get HashOperations from your RedisTemplate HashOperations<String, Integer, int[]> hashOps = redisTemplate.opsForHash(); // Store the entire map as a Redis Hash (use a unique key like your entity's ID) hashOps.putAll("my-entity:123", myEntity.getMymap());
To retrieve it:
Map<Integer, int[]> retrievedMap = hashOps.entries("my-entity:123"); myEntity.setMymap(retrievedMap);
This approach is ideal if you need to access or modify individual entries in the Map without loading the entire object.
内容的提问来源于stack exchange,提问作者Cyber




