Версионная сериализация в Java - PullRequest
4 голосов
/ 22 августа 2009

У меня есть простой класс Java, который мне нужно сериализовать, чтобы сохранить как значение в СУБД или хранилище значений ключей. Класс - это просто набор свойств простых типов (нативные типы или Карты / Списки нативных типов). Проблема в том, что класс, вероятно, будет развиваться с течением времени (вероятно: добавление новых свойств, менее вероятно, но все еще возможно: переименование свойства, изменение типа свойства, удаление свойства).

Я бы хотел иметь возможность корректно обрабатывать изменения в версии класса. В частности, когда делается попытка десериализации экземпляра из более старой версии, я хотел бы иметь возможность указать какой-либо тип обработчика для управления переходом более старого экземпляра в новейшую версию.

Я не думаю, что встроенная сериализация Java здесь уместна. Прежде чем я попытаюсь развернуть свое собственное решение, мне интересно, знает ли кто-нибудь какие-либо существующие библиотеки, которые могут помочь? Я знаю множество альтернативных методов сериализации для Java, но я специально ищу что-то, что позволило бы мне изящно обрабатывать изменения в определении класса со временем.

Edit:

Что бы это ни стоило, я закончил тем, что остановился на Protocol Buffer (http://code.google.com/p/protobuf/) сериализация, так как он гибок для добавления и переименования полей, в то же время находясь на меньшем количестве кода, который я должен поддерживать (в отношении пользовательских Сериализация Java с использованием readObject / writeObject).

Ответы [ 5 ]

4 голосов
/ 22 августа 2009

Сериализация Java позволяет настраивать последовательную форму, предоставляя методы readObject и writeObject. Вместе с ObjectInputStream.readFields, ObjectOutputStrean.putFields и определением serialPersistentFields сериализованная форма может не иметь отношения к фактическим полям в классе реализации.

Тем не менее, сериализация Java создает непрозрачные данные, которые не поддаются чтению и записи другими методами.

2 голосов
/ 22 августа 2009

Возможно, вам следует сопоставить ваш класс Java с реляционной моделью. Сбросить какой-либо язык сериализованного большого двоичного объекта в столбец базы данных - ужасный подход.

1 голос
/ 22 августа 2009

Это довольно просто использовать для чтения и записи объектов.

Попробуйте установить для serialversionuid фиксированное значение, а затем определить статическое конечное поле для вашей версии. Затем readobject может использовать оператор switch для создания полей в зависимости от версии. Мы используем это для хранения исторических данных в нашей файловой системе. Это очень быстро при поиске - настолько, что пользователи не могут заметить разницу.

0 голосов
/ 22 августа 2009

Никогда не пробовал, но вы можете что-то сделать с помощью специального загрузчика, чтобы загрузить правильную версию файла класса во время выполнения для десериализованного объекта.

0 голосов
/ 22 августа 2009

У меня была похожая проблема. Я обнаружил, что Java serialVersionUID мало помогает, когда у вас несколько версий объектов. Поэтому я выкатил свой.

Вот что я делаю, чтобы сохранить наши пользовательские сессии,

  1. В моей БД, кроме поля BLOB для сериализованных объектов, я добавил столбец версии.
  2. Всякий раз, когда мы меняем объект сеанса, я сохраняю старый класс, например SessionV3.
  3. Сессия всегда записывается в БД с номером текущей версии.
  4. При чтении сеанса он десериализуется в объект сеанса напрямую, если версия является текущей. В противном случае он десериализуется в старый объект и вручную копируется в текущий объект сеанса (SessionV3 => Session).
  5. Время от времени мы запускаем скрипт БД для удаления реальных старых версий сессий, чтобы мы могли очистить старые сессии от кода. Если мы заботимся о старых сессиях, мы можем также преобразовать их.

Возможно, есть более простой способ сделать это, но наш подход дает нам большую гибкость.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...