2010-08-26 97 views
2

我们有一个使用大量序列化的生产系统。基本上做的是将名为ProcessData的对象作为字节数组存储在jbpm数据库中。因此这是序列化的。反序列化问题

考虑以下对象。

public class ProcessData implements Serializable { 
    private static final long serialVersionUID = -4859440951531011062L; 

    public void getX() { 
    //not important 
    } 
} 

现在让我们说我们有存储在jBPM数据库以字节数组的这个对象,我们在生产中使用这个。

现在,以后我们想用一个新的数据

public class ProcessData implements Serializable { 
    private static final long serialVersionUID = -4859440951531011062L; 

    public void getX() { 
    //not important 
    } 

    public void getY() { 
    //not important 
    } 
} 

现在的问题是升级此过程数据对象时JBPM加载old存储过程数据对象,我们得到一个异常现在 Caused by: java.io.InvalidClassException: my.package.ProcessData; local class incompatible: stream classdesc serialVersionUID = 6651422488035743444, local class serialVersionUID = -7966721901330644987

我的问题是的,我们如何解决这个问题?我们如何读取序列化对象以及如何在这个新类中进行转换。它甚至有可能吗?请记住,我们对JBPM库的控制有限。

回答

2

看起来你在这两种情况下都没有使用示例代码,因为在你的例子中你定义了serialVersionUID(这很好),并且它在前后是一样的,但是在你的错误中,UID是不同的。要发生这种情况,UID要么没有定义(因此生成),要么在版本之间进行更改。由于类签名不同,生成的案例也会导致版本之间发生更改。

无论哪种情况,这都是预期的行为。

它看起来像运行的真正的代码实际上并不符合你的例子。要加载旧代码,您必须在新版本中设置UID以匹配已存在于持久类中的UID(6651422488035743444L)。另外,如果您使用简单的数字(如版本1,2,3),则更容易管理UID。

+0

没有示例代码就是这样。示例代码。不过,我可以确保你'serialVersionUID'完全相同。 – 2010-08-26 16:20:40

+0

也许UID没有正确声明,因此实际上并未在其中一个版本中使用。如果您可以访问旧版本和新版本的.class文件,则可以对它们运行serialver以确认UID与您期望的相同。 – Robin 2010-08-26 16:28:35

+0

让我们说参数serialVersionUID是一样的,并忽略这个异常。是否有可能改变一个类(通过只添加方法,不改变名称),然后反序列化它以加载新类中的“旧”类? – 2010-08-26 16:50:34