2015-06-29 53 views
0

我嘗試將我的Java pet-project從手寫SQL切換到Ebean。當我現在運行該項目時,我收到消息Ebean無法序列化貨幣

Was unable to use reflection to find a constructor and appropriate getters forimmutable type interface j`avax.money.MonetaryAmount` 

後跟更多與javamoney相關的錯誤。

我知道MonetaryAmont有一個私人構造函數,並通過公共靜態方法實例化。我如何告訴Ebean如何序列化MonetaryAmount?

回答

2

我已經放棄了Ebean並使用了Eclipselink。具有諷刺意味的是,我在那裏找到了我的問題的答案。因此,對於與我在這裏類似的情況下的人是我應該做的:

我一直在尋找的東西叫做ScalarTypeConverter。他們在Ebean中沒有很好的記錄。但是有一些關於它們的javadoc和至少一個關於GitHub的問題。

在Ebean中不需要實現可序列化

0

請仔細閱讀this

下面是摘錄從那裏

類的公有接口串行化

串行化是通過實現 java.io.Serializable接口的類啓用。沒有實現這個接口的類將沒有任何狀態序列化或反序列化。 可序列化類的所有子類本身都是可序列化的。 序列化接口沒有方法或字段,並且僅用於識別可序列化的語義 。

要允許不可序列化類的子類型進行系列化, 亞型可以承擔保存和恢復超類型的公共狀態 ,保護的責任,以及(如果可訪問)包 領域。子類型只有在它所擴展的類 有一個可訪問的無參數構造函數來初始化類的狀態時纔可以承擔這種責任。如果這個 不是這種情況,那麼聲明一個類Serializable是錯誤的。該錯誤將在運行時檢測到。

在反序列化過程中,不可序列化的類的字段將使用 類的公共或受保護的無參數構造函數初始化爲 。對於可序列化的子類,必須可訪問無參數構造函數。序列化子類的字段將從流中恢復爲 。

遍歷圖時,可能會遇到不支持Serializable接口的對象。在這種情況下,將拋出NotSerializableException,並將標識不可序列化對象的類 。

類的序列化和反序列化 過程中需要進行特殊處理必須實現這些 準確簽名的特殊方法:

私人無效的writeObject(java.io.ObjectOutputStream中出) 拋出IOException異常私人無效的readObject(java中。 io.ObjectInputStream中) 拋出IOException,ClassNotFoundException; private void readObjectNoData() throws ObjectStreamException;

writeObject方法負責爲其特定類寫入 對象的狀態,以便相應的readObject方法可以恢復它。通過調用out.defaultWriteObject可以調用保存Object的 字段的默認機制。方法 不需要關注屬於其超類或子類的狀態。通過使用writeObject方法將個體 字段寫入ObjectOutputStream或使用DataOutput支持的基元數據類型的方法寫入 可以保存狀態。

readObject方法負責從流中讀取數據並且 恢復類字段。它可能會調用in.defaultReadObject到 調用默認機制來恢復對象的非靜態字段和 非瞬態字段。 defaultReadObject方法使用 流中的信息來分配保存在流中的對象的字段,其中 是當前對象中相應命名的字段。這將處理 這個類已經演變爲添加新字段的情況。方法 不需要關注屬於其超類或子類的狀態。通過使用writeObject方法將個體 字段寫入ObjectOutputStream或使用DataOutput支持的基元數據類型的方法寫入 可以保存狀態。

的readObjectNoData方法是負責初始化對象的狀態 對其特定類中的情況下,所述 序列化流不列出給定類作爲對象被反序列的 一個超類。在接收方使用與發送方不同的反序列化的實例類的版本,並且接收方的版本 擴展未由發送方版本擴展的類時,可能會發生這種情況。如果序列化流已被篡改,則也可能發生此 ;因此, readObjectNoData可用於正確初始化反序列化對象 ,儘管存在「敵意」或不完整的源碼流。

需要指定一個替代目的是

序列化的類對象寫入到該流時,可以使用應實現此 與精確簽名特殊方法:

ANY-ACCESS-MODIFIER對象writeReplace()拋出 ObjectStreamException;

如果存在方法 ,則可以通過序列化來調用此WriteReplace方法,該方法可以通過序列化對象的 類中定義的方法訪問。因此,該方法可以具有私有的,受保護的和包私有訪問。子類訪問此 方法遵循java可訪問性規則。

當從流中讀取其實例爲 的實例時,需要指定替換的類應該使用 確切簽名實現此特殊方法。

ANY-ACCESS-MODIFIER Object readResolve()throws ObjectStreamException;

此readResolve方法遵循與writeReplace相同的調用規則和 可訪問性規則。

序列化運行時相關聯,每個序列化類一個 版本號,稱爲的serialVersionUID,該期間 反序列化用於驗證序列化 對象的發送者和接收者都加載的類該對象能與 兼容尊重系列化。如果接收方已加載 對象的類,該對象的serialVersionUID與 對應的發送者類不同,則反序列化將導致InvalidClassException。可序列化類可以通過聲明名爲 「的serialVersionUID」字段必須是靜態的,最終明確地聲明自己的 的serialVersionUID,並long類型:

ANY-ACCESS-MODIFIER靜態最後的serialVersionUID長= 42L;

如果一個序列化類沒有顯式聲明 的serialVersionUID,則序列化運行時將基於各方面的類 ,作爲Java(TM)對象序列化 描述計算該類的 默認的serialVersionUID值規範。然而,強烈建議所有 序列化的類顯式聲明的serialVersionUID值,因爲 默認serialVersionUID的計算是類 細節,可能會因編譯器實現變化高度敏感,並能 期間 反序列化從而導致意外InvalidClassExceptions。因此,爲了保證跨不同java編譯器實現的一致的serialVersionUID 值,可序列化的類必須聲明顯式的serialVersionUID值。它也是 強烈建議顯式serialVersionUID聲明儘可能使用 專用修飾符,因爲這些聲明僅適用於 立即聲明的類 - serialVersionUID字段不是 作爲繼承成員有用。數組類不能聲明明確的 serialVersionUID,因此它們始終具有默認計算值,但 對於 數組類無需匹配serialVersionUID值的要求。

+0

這看起來更像是一條評論。這是很多文字。你到底在說什麼? – Reimeus

+0

@Reimeus這個問題本身就是一個廣泛的問題。他遇到了麻煩,因爲他根本不知道如何創建一個可串行化的類。當他試圖序列化MonetaryAmount類時,可能有不止一個原因爲什麼出現問題。上面的文本可能會很長,但是在實現Serializable接口之前閱讀是很有必要的。 – Alp

+0

@Alp這是一個廣泛的問題?我特別詢問了如何使用Ebean從外部庫(實現Serializable btw)中存儲一個類型。 –