Hibernate 常見誤區1——正確區分值對象和實體對象
值對象和實體對象是hibernate的重要概念,當然在jpa中也有相應的概念他們在語義上是相同的。常常聽到人們抱怨hibernate中對象之間的映射關係配置很難,而且經常出現一些莫名奇妙的問題。其真正原因是沒有正確的區分值對象和實體對象而進行了錯誤的設計(其實很多就沒有值對象的概念,而在系統將所有的對象都歸結爲了實體)。
一、什麼是值對象?
舉個例子:如果你又User類和Address類,對於每個具體的User有對應的Address,當然這個Address可以是多個(家庭地址、公司地址)等等。而這些地址只能依賴於User類而存在,並且不存在其他對象對某個具體Address的引用(此處忽略,兩個人有同一地址的情況)。這時候Address就是一個值對象。
更抽象的,對於一個實體如何區分是值對象和實體對象主要從一下三點考慮
1、是否有一個依賴的生命週期,如果此對象依賴於另一個對象的生滅,就認爲他是有一個依賴的生命週期的。
2、是否需要它們自己的同一性(java中體現爲 == 和 equals() 方法,數據庫中體現爲主鍵是否相等),就是說你的代碼中會不會去比較兩個對象是否具有同一性,
在上例中體現爲我們永遠不會去比較連個地址是否相等(== 或者 equlas());
3、是否需要支持共享引用。
如果一個對象有一個依賴的生命週期,不需要它們自己的同一性,並且不必支持共享引用的話它就是個值類型的對象。
例如:報銷單下有報銷明細,報銷明細就是一個值對象,再如一個商品有它的多張照片,照片就是值對象,更一般的java中的String,Integer,Double.....都是值對象
二、爲什麼要使用值對象。
Hibernate對值對象的的映射提供了特別的支持,如果你有一個1對多的關聯,而且你希望在1的一方控制一切的話,更具經驗多數情況下多的一方是一個值對象。如果是值對象你可以避免考慮級聯更新的問題,孤兒的問題等等。而交給hibernate去控制
常見值對象集合的映射如下:(已商品和圖像(路徑)爲例)
set:
<set name="images" table="ITEM_IMAGE">
<key column="Item_id"/>
<element type="string" column="filename" not-null="true"/>
</set>
list
<list name="images" table="ITEM_IMAGE">
<key column="Item_id"/>
<list-index column="prosition"/>
<element type="string" column="filename" not-null="true"/>
</set>
map
<map name="images" table="ITEM_IMAGE">
<key column="Item_id"/>
<map-index column="imagename" type="stirng"/>
<element type="string" column="filename" not-null="true"/>
</map>