2010-01-07 52 views
85

問題在標題中。下面我剛剛描述了我的一些想法和發現。何時以及爲什麼JPA實體應該實現Serializable接口?

當我有非常簡單的領域模型(3表沒有任何關係),我所有的實體沒有實現Serializable。

但是,當域模型變得更復雜時,我得到了RuntimeException,它說我的一個實體沒有實現Serializable。

我使用Hibernate作爲JPA實現。

我在想:

  1. 它是特定於供應商的要求/行爲?
  2. 我的序列化實體會發生什麼?它們是否應該可序列化以用於存儲或傳輸?
  3. 在哪一刻,有必要讓我的實體可序列化?

回答

33

這通常發生在混合使用HQL和本機SQL查詢時。在HQL中,Hibernate將您傳遞的類型映射到數據庫理解的任何內容。當你運行本地SQL時,你必須自己做映射。如果你不這樣做,那麼默認的映射就是序列化參數並將其發送到數據庫(希望它理解它)。

34

你需要你的實體是Serializable如果你需要他們過線上(它們序列一些其他表示)轉移,將其存儲在HTTP會話(後者又由servlet序列化到硬盤容器)等。

只是爲了持久性,Serializable是不需要的,至少在Hibernate中是這樣。 但最好讓它們成爲Serializable

+2

我不知道,也許我的實體被隱式轉移到某處。我使用hibernate + spring + jsf和Tomcat。在這個鏈中轉移可以發生在哪裏? – Roman 2010-01-07 14:31:52

4

如果要序列化它們,類必須實現Serializable。這與JPA沒有直接關係,並且JPA規範不要求實體是可序列化的。如果Hibernate真的抱怨這個,我想這是一個Hibernate的bug,但我想你直接或間接地對這些實體做了一些其他的事情,這些事情要求它們是可序列化的。

92

根據JPA規格:

如果一個實體實例是由值傳遞作爲分離對象(例如,通過遠程接口),該實體類必須實現Serializable接口。

「JSR 220:企業JavaBeansTM,3.0版本的Java持久性API 3.0版本,最終版本2006年5月2日,」

+11

(+1)看規格總是富有成果 – Bozho 2010-01-07 16:57:00

+9

我看不出爲什麼這麼多upvotes。該OP說,模型更簡單時不需要。通過Java序列化遠程發送對象總是要求對象是可序列化的,而不管它的複雜性如何。顯然這不是OP的用例。 – Robin 2015-06-22 14:29:24

+0

我對hibernate不太確定,但是對於其他JPA提供者,有些操作需要提供者創建實體(對象)的副本。 'Serializable'可能對此有所幫助,並且在持久性方面比「Cloneable」更加一致。 – JimmyB 2015-07-06 10:09:38

4

我相信你的問題涉及到具有複雜類型(類)的字段,沒有註釋。在這種情況下,默認處理將存儲在它的對象的序列化形式在數據庫中(這可能不是你的意思做) 例子:

Class CustomerData { 
    int getAge(); 
    void setAge(int age); 
} 

@Entity 
Class Customer { 
    CustomerData getCustomerData(); 
    void setCustomerData(CustomerData data) 
} 

在上述情況下的CustomerData將被保存在數據庫中的字節數組字段以序列化的形式存在。

8

補充了引用JSR-317規範的Conor的不錯答案。通常,EAR項目由EJB模塊組成,EJB模塊通過遠程接口公開EJB。在這種情況下,您需要讓實體bean可序列化,因爲它們在遠程EJB中聚合,並且構建爲通過網絡進行連接。

沒有CDI的JEE6戰爭項目:可以包含由不可序列化的JPA實體支持的EJB lite。

與CDI的JEE6戰爭項目:Beans that use session, application, or conversation scope must be serializable, but beans that use request scope do not have to be serializable.因此,基礎JPA實體bean - 如果任何 - 會遵循相同的語義。

1

按照hibernate docs,同時使用@JoinColumn批註:

它有一個多個參數命名referencedColumnName。該參數聲明將用於連接的目標實體中的列。請注意,將referencedColumnName用於非主鍵列時,關聯的類必須爲Serializable

0

這也是當您將錯誤類型的ID作爲第二個參數傳遞給em.find()(即傳遞實體本身而不是它的ID)時引發的錯誤。我還沒有發現它有必要實際聲明JPA實體可序列化 - 除非你使用aman描述的referencedColumnName,否則它並不是必須的。

0

遠程命中使用郵遞員或ajax或角js等.....可能導致重複週期與傑克遜的StackOverflow異常fasterxml.So,最好使用序列化程序。

相關問題