Hibernate的實體類中為什么要繼承Serializable?
hibernate有二級緩存,緩存會將對象寫進硬盤,就必須序列化,以及兼容對象在網絡中的傳輸 等等。
java中常見的幾個類(如:Interger、String等),都實現了java.io.Serializable接口。
實現 java.io.Serializable 接口的類是可序列化的。沒有實現此接口的類將不能使它們的任一狀態被序列化或逆序列化。序列化類的所有子類本身都是可序列化的。這個序列化接口沒有任何方法和域,僅用於標識序列化的語意。
確切的說應該是對象的序列化,一般程序在運行時,產生對象,這些對象隨着程序的停止運行而消失,但如果我們想把某些對象(因為是對象,所以有各自 不同的特性)保存下來,在程序終止運行后,這些對象仍然存在,可以在程序再次運行時讀取這些對象的值,或者在其他程序中利用這些保存下來的對象。這種情況 下就要用到對象的序列化。
只有序列化的對象才可以存儲在存儲設備上。為了對象的序列化而需要繼承的接口也只是一個象征性的接口而已,也就是說繼承這個接口說明這個對象可以 被序列化了,沒有其他的目的。之所以需要對象序列化,是因為有時候對象需要在網絡上傳輸,傳輸的時候需要這種序列化處理,從服務器硬盤上把序列化的對象取 出,然后通過網絡傳到客戶端,再由客戶端把序列化的對象讀入內存,執行相應的處理。
將二級緩存中的內容持久化保存下來,便於恢復緩存的信息,hibernate的緩存機制通過使用序列化,斷定應該是基於序列化的緩存,如沒有 serializable接口,在序列化時,使用objectOutputStream的write(object)方法將對象保存到文件時將會出現異常。
Hibernate並不要求持久化類必須實現java.io.Serializable接口,但是對於采用分布式結構的Java應用,當Java對象在不同的進程節點之間傳輸時,這個對象所屬的類必須實現Serializable接口,此外,在Java Web應用中,如果希望對HttpSession中存放的Java對象進行持久化,那么這個Java對象所屬的類也必須實現Serializable接口。
Java的序列化ID的作用
簡單來說,Java的序列化機制是通過在運行時判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體(類)的serialVersionUID進行比較,如果相同就認為是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常。
當實現java.io.Serializable接口的實體(類)沒有顯式地定義一個名為serialVersionUID,類型為long的變量時,Java序列化機制會根據編譯的class自動生成一個serialVersionUID作序列化版本比較用,這種情況下,只有同一次編譯生成的class才會生成相同的serialVersionUID 。
如果我們不希望通過編譯來強制划分軟件版本,即實現序列化接口的實體能夠兼容先前版本,未作更改的類,就需要顯式地定義一個名為 serialVersionUID,類型為long的變量,不修改這個變量值的序列化實體都可以相互進行串行化和反串行化。