3

I have stored an object in redis, say Class StorageConnection,

public void storeSecureConnection(String uniqueKey, Object storageConnection) {
        redisTemplateAdmin.opsForValue().set(uniqueKey, storageConnection);

}

Now, I have changed the className from StorageConnection to DataConnection. All the fields and UID remains intact.

It's now giving me an SerializationException on

public DataConnection getAdminDataObject(String uniqueKey) {    
        return  (DataConnection) redisTemplateAdmin.opsForValue().get(uniqueKey);
    }

Is there any trick that I can deserialize it with new className?

Edit:

Here's RedisTemplate Initialization:

@Service
public class AdminDataBaseServiceImpl{
    private RedisTemplate<String, Object> redisTemplateAdmin;
    private HashOperations hashOps;

    private AdminDataBaseServiceImpl(RedisTemplate<String, Object> redisTemplateAdmin) {
    this.redisTemplateAdmin = redisTemplateAdmin;
    hashOps=redisTemplateAdmin.opsForHash();
}
Abhishek
  • 688
  • 6
  • 21

3 Answers3

1
"{\"@class\":\"org.crm.backend.repository.redis.dto.TripInfoDto\",\"tripId\":44271,\"demandUserId\":11811,\"demandUserPhoneNumber\":\"7777777777\",\"supplierId\":1223,\"supplierPhoneNumber\":\"7777777777\",\"criticalOn\":\"DEMAND\",\"loadingBucket\":430119,\"tripType\":\"RETAIL\",\"creationTime\":1548422893462}"

This is value of key in Redis in my case, to deserialise with another class I can update value in Redis for that key.

hset mapKey 44271 "{\"@class\":\"org.crm.backend.repository.redis.dto.AnotherClass\",\"tripId\":44271,\"demandUserId\":11811,\"demandUserPhoneNumber\":\"9929011689\",\"supplierId\":1223,\"supplierPhoneNumber\":\"9929014797\",\"criticalOn\":\"DEMAND\",\"loadingBucket\":430119,\"tripType\":\"RETAIL\",\"creationTime\":1548422893462}"

So just check value in your case, if you can update the class name in it's value

lonwolf
  • 81
  • 1
  • 6
0

It is not nessesary to use Serializeable. You can serialize it to a format that does not do class checking. Example of such format can be a simple byte array, it can be json it can be a more advanced serialization framework as Kryo. You can use protobuff , here is an example : https://codeclimate.com/blog/choose-protocol-buffers/

All in all I think JSON is the simplest format to go for. Good balance between performance, readibility and searchability.

Alexander Petrov
  • 9,204
  • 31
  • 70
  • But I can't change my existing design. I can change the deserialization process, but we have much data that is already serialized and stored in data. I can't afford to loose that data. – Abhishek Feb 19 '19 at 13:11
  • Is it so difficult to migrate it ? :) There is no go around the Classname check. At least not one that I know of immediatly. – Alexander Petrov Feb 19 '19 at 13:13
  • But a migration should not be that difficult theoreticaly. You just need to read data through the old format and re insert it with the new serializer. – Alexander Petrov Feb 19 '19 at 13:14
  • Here is one stackoverflow answer that reviews exactly what I have neen saying. You can read it from another class: https://stackoverflow.com/questions/2358886/how-can-i-deserialize-the-object-if-it-was-moved-to-another-package-or-renamed – Alexander Petrov Feb 19 '19 at 13:16
  • I'm afraid but this can't be done. Anything which I can do by overriding RedisDeserializers? – Abhishek Feb 19 '19 at 13:22
0

I used GenericJackson2JsonRedisSerializer to serialize the object and was storing in redis. To change the class name, I used StringRedisSerializer to deserialize, changed the classname and again stored in Redis with StringRedisSerializer.

Then used, as usual, GenericJackson2JsonRedisSerializer to deserialize the object with new classname. It worked.

Abhishek
  • 688
  • 6
  • 21