You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动