2010-08-26 158 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