The @class property is used to include the class information of an object when it is serialized, allowing it to be accurately restored to the correct class type during deserialization.
(i’m using jackson objectmapper)
{
"@class": "com.a.b.c.Dto",
"id": 1,
"name": "john"
...
}
Now, let’s say this data is stored in a Redis cache.
If the class path changes in the new version to com.a.b.c.d.Dto
, it can cause issues, especially when the old and new versions of the server are running simultaneously.
The new version server will fail to deserialize this data because the com.a.b.c.Dto
class is no longer available at that location.
So, how can we solve this problem? I thought of a couple of potential solutions:
-
Gradual Deployment:
Deploy the new version while still keeping the old version’s data.
-> Clear the cache. ->
Redeploy after removing the old version data. -
Removing the Class Information:
Remove the class information by configuring objectMapper.deactivateDefaultTyping() or similar settings.
However, this causes issues with polymorphism support.
Will the following test failure actually be a problem in practice?
@Test
public void testDeactivateDefaultTyping() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.deactivateDefaultTyping(); // Disable class information
Animal myDog = new Dog("Buddy", "Golden Retriever");
// Serialization
String jsonString = objectMapper.writeValueAsString(myDog);
System.out.println("Serialized with disableDefaultTyping: " + jsonString);
// Deserialization
Animal deserializedAnimal = objectMapper.readValue(jsonString, Animal.class);
System.out.println("Deserialized Animal: " + deserializedAnimal.getClass().getName());
// Assertions
assertEquals(Dog.class, deserializedAnimal.getClass());
assertEquals("Buddy", deserializedAnimal.name);
assertEquals("Golden Retriever", ((Dog) deserializedAnimal).breed);
}
static class Animal {
public String name;
public Animal() {}
public Animal(String name) {
this.name = name;
}
}
static class Dog extends Animal {
public String breed;
public Dog() {}
public Dog(String name, String breed) {
super(name);
this.breed = breed;
}
}
1