Java中的版本化序列化

时间:2009-08-21 23:18:51

标签: java version-control serialization

我有一个简单的Java类,我需要序列化以存储为RDBMS或键值存储中的值。该类只是简单类型属性的集合(本机类型或本地类型的映射/列表)。问题是该类可能会随着时间的推移而发展(可能:添加新属性,不太可能但仍然可能:重命名属性,更改属性类型,删除属性)。

我希望能够优雅地处理类版本中的更改。具体来说,当尝试从旧版本反序列化实例时,我希望能够指定某种处理程序来管理旧实例到最新版本的转换。

我不认为Java的内置序列化在这里是合适的。在我尝试推出自己的解决方案之前,我想知道是否有人知道任何可能有用的现有库?我知道Java有很多替代序列化方法,但是我特意寻找的东西可以让我优雅地处理类定义随时间的变化。

修改

为了它的价值,我最终选择了协议缓冲区(http://code.google.com/p/protobuf/)序列化,因为它可以灵活地添加和重命名字段,同时我需要维护的代码更少(参考自定义)使用readObject / writeObject进行Java序列化。

5 个答案:

答案 0 :(得分:4)

Java序列化允许通过提供readObjectwriteObject方法来自定义序列表单。与ObjectInputStream.readFieldsObjectOutputStrean.putFields和定义serialPersistentFields一起,序列化表单可能与实现类中的实际字段无关。

但是,Java序列化产生的不透明数据不适合通过其他技术进行读写。

答案 1 :(得分:2)

也许您应该将Java类映射到关系模型中。将一些语言序列化的blob转储到数据库列中是一种可怕的方法。

答案 2 :(得分:1)

使用读写对象非常简单。

尝试将serialversionuid设置为固定值,然后为您的版本定义静态最终字段。然后,readobject可以使用switch语句根据版本构造字段。我们使用它来存储我们文件系统的历史数据。它的检索速度非常快 - 以至于用户无法区分它们。

答案 3 :(得分:0)

我有类似的问题。我发现当你有多个版本的对象时,Java的serialVersionUID并没有多大帮助。所以我推出了自己的。

以下是我保存用户会话的方法,

  1. 在我的数据库中,除了序列化对象的BLOB字段外,我还添加了一个版本列。
  2. 每当我们更改会话对象时,我都会保存旧类,例如SessionV3。
  3. 会话始终以当前版本号写入数据库。
  4. 当读取会话时,如果版本是最新的,则直接将其反序列化为会话对象。否则,它被反序列化为旧对象并手动复制到当前会话对象(SessionV3 => Session)。
  5. 我们运行一个数据库脚本来删除真正的旧会话版本,以便我们可以从代码中清除旧会话。如果我们关心旧会话,我们也可以选择转换它们。
  6. 可能有更简单的方法,但我们的方法为我们提供了最大的灵活性。

答案 4 :(得分:0)

从未尝试过,但您可以使用自定义引导加载程序执行某些操作,以便在运行时为正在反序列化的对象加载类文件的正确版本。