简体   繁体   中英

Jackson ObjectMapper readValue expected behavior when class properties change

I have a requirement to change properties of a class which is being serialized/deserialized by ObjectMapper.

This is my class.

// Old version
Class A {
    String id;
    String name;
}

// New version
Class A {
    String id;
    String firstName;
    String secondName;
}

I serialize the object ObjectMapper.writeValueAsString() , send it to a queue to process it later, and when received, deserialize it via ObjectMapper.readValue() . What is the expected behavior of readValue() if the old version of Class A is serialized, but when deserializing - Class A has been updated to the new version.

Will firstName and secondName be null? Or readValue() throw an exception?

And what is the solution here to make the changes smoothly.

To answer the first part as to what is the expected behavior if older object is deserialized, objectMapper.readValue() will deserialize with firstName and secondName being null while name being whatever was set. (I was expecting an exception which is not the case).

On how to make the transition:

I will not delete name . I will keep it along with firstName and secondName .

// Intermediate version
Class A {
    String id;
    String name;
    String firstName;
    String secondName;
}

name will be a dummy holder, and not used when serializing.

public void write(int id, String firstName, String secondName) {
    A a = new A();
    a.setId(id);
    a.setFirstName(firstName);
    a.setSecondName(secondName);
    bufferedWriter.write(objectMapper.writeValueAsString(a));
}

Based on null check I will know whether the object belongs to older version or newer version.

public void read(String message) {
    A a = objectMapper.readValue(message);

    if(a.getName() != null) {
        // This object is older version of class A
        System.out.println("Name: " + a.getName());
        metric.emit("OldObjectA", 1);
    } else {
        // This object is newer version of class A
        System.out.println("Name: " + a.getFirstName() + " " + a.getSecondName())
    }
}

Once I'm sure I am not reading objects of older version, I will make the complete transition by removing name .

// Newer version
Class A {
    String id;
    String firstName;
    String secondName;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM