Ожидаемое поведение Джексона ObjectMapper readValue при изменении свойств класса - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть требование изменить свойства класса, который сериализуется / десериализуется ObjectMapper.

Это мой класс.

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

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

Я сериализую объект ObjectMapper.writeValueAsString(), отправляю его в очередь для последующей обработки, а при получении десериализую через ObjectMapper.readValue(). Каково ожидаемое поведение readValue(), если старая версия класса A сериализуется, но при десериализации - класс A был обновлен до новой версии.

firstName и secondName будут нулевыми? Или readValue() выбросить исключение?

И каково здесь решение, чтобы плавно вносить изменения.

1 Ответ

0 голосов
/ 07 ноября 2018

Чтобы ответить на первую часть относительно того, каково ожидаемое поведение, если десериализован более старый объект, objectMapper.readValue() десериализуется с firstName и secondName, равными null, тогда как name будет тем, что было установлено. (Я ожидал исключения, которого нет).

О том, как сделать переход:

Я не буду удалять name. Я буду держать его вместе с firstName и secondName.

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

name будет фиктивным держателем и не будет использоваться при сериализации.

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));
}

На основе проверки на ноль я узнаю, принадлежит ли объект более старой или более новой версии.

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())
    }
}

Как только я уверен, что не читаю объекты более старой версии, я сделаю полный переход, удалив name.

// Newer version
Class A {
    String id;
    String firstName;
    String secondName;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...