有人认为使用Java的默认序列化方法将对象存储在blob列的数据库中是个好主意。 这些对象的结构由另一个组控制,他们将字段类型从BigDecimal更改为Long, 但我们数据库中的数据保持不变。 现在我们无法读取对象,因为它会导致ClassCastExceptions。
我尝试通过编写自己的readObject方法来覆盖它, 但是抛出StreamCorruptedException,因为默认的writeObject方法写了什么。
如何使我的readObject调用表现得像Java的默认调用? 我可以跳过一定数量的字节来获取数据吗?
答案 0 :(得分:2)
Externalizable
允许您完全控制序列化/反序列化。但这意味着你负责编写和阅读每个领域,
如果使用默认序列化写出某些内容并且您希望通过Externalizable
读取内容时遇到困难。 (或者说,它是不可能的。如果您尝试使用Externalizable
读取使用默认方法序列化的对象,它只会抛出异常。)
如果您对输出完全没有控制权,那么您唯一的选择是保留该类的两个版本:使用旧版本的默认反序列化,然后转换为新版本。这个解决方案的优点是它可以保持"脏"代码在一个地方,与你漂亮干净的物品分开。
同样,除非你想做一些非常复杂的事情,你最好的选择是把旧班保留为"运输" bean并将您的代码实际使用的类重命名为其他类。
答案 1 :(得分:1)
如果您想阅读数据库中已有的内容,您唯一的选择就是让他们重新更改课程,并提醒您依赖课程定义,因为它是当班级被序列化时。仅仅实现你自己的readObject()调用就无法解决这个问题,如果这个类在别人的控制之下,那你无论如何也无法做到。
如果您准备丢弃现有数据,那么您可以从自定义序列化,writeReplace()/ readResolve(),Externalizable,...或其他机制(如XML)开始,有许多其他选择。
但是,如果你想让第三方在他们感觉到的时候改变事物,你总会遇到这种或那种问题。
BigDecimal to Long听起来像是一个逆行的步骤。
答案 2 :(得分:0)
在您的类中实现readObject和readObjectNoData方法。
使用ObjectInoutStream.readObject
读取相应的类型并将其转换为新类型
有关详细信息,请参阅Serializable接口API。
如果您控制序列化为blob的类的源,则只能轻松修复此问题。 如果你不控制这个班级, 那么你只有一些有限和困难的选择:
接下来你必须做其中一个