one-to-one在hibernate中可以用來作為兩張表之間的主鍵關(guān)聯(lián),這也是hibernate中主鍵關(guān)聯(lián)的一種用法,這樣在一張表中的ID,在生成另外一張表的同時(shí)回自動(dòng)插入到相應(yīng)的ID字段中去,相應(yīng)的XML文件設(shè)置比較簡(jiǎn)單,舉例如下:
<!-- 建立一對(duì)一的到Address的映射,這個(gè)是寫在User的XML配置文件中的 -->
<!-- 相應(yīng)的User bean(PO)中也要添加屬性 com.xx.Address address-->
<one-to-one name="address" cascade="all" class="com.xx.Address"/>
<!-- cascade的屬性設(shè)置不再重復(fù)了,可以查看hibernate文檔 -->
<!-- 建立一對(duì)一的到User的映射,這個(gè)是寫在Address的XML配置文件中的 -->
<!-- 相應(yīng)的Address bean(PO)中也要添加屬性 com.xx.User user--> -->
<one-to-one name="user" class="com.xx.User" constrained="true"/>
為了在Address中使用User中的主鍵ID值,我們需要設(shè)置Address中的主鍵生成規(guī)則,如下所示,采用foreign關(guān)鍵字
<id column="ID" name="id" type="long" unsaved-value="0">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
這里需要注意的是property的屬性值必須與上面到User的映射所填寫的name屬性值一致,這樣就完成了one-to-one的映射關(guān)系。
上面的過程都很簡(jiǎn)單,下面我來說說這里需要注意的地方:
1. 在設(shè)置屬性ID的時(shí)候必須注意字段的長(zhǎng)度,如筆者這樣使用oracle的sequence來生成ID,其長(zhǎng)度有14位之長(zhǎng),則應(yīng)選擇hibernate類型long,對(duì)應(yīng)的實(shí)體中應(yīng)選擇Long,這樣不會(huì)出現(xiàn)溢出的情況。
2. 在測(cè)試的時(shí)候必須要注意這兩張表之間因?yàn)橐呀?jīng)存在了一對(duì)一的關(guān)系,所以我們不能只寫
user.setAddress(address);
而忽略了
address.setUser(user);
這樣在做插入的時(shí)候會(huì)報(bào)出attempted to assign id from null one-to-one property: address的錯(cuò)誤,這一點(diǎn)初學(xué)者會(huì)經(jīng)常犯,筆者也是其中之一。
3. 如果不寫cascade="all"或者寫成cascade="none"的話,即使你寫了
user.setAddress(address);
address.setUser(user);
也不會(huì)發(fā)生任何事情,只有user會(huì)被存儲(chǔ)。
以上是一些筆者經(jīng)歷的小經(jīng)驗(yàn),如果有不對(duì)的地方歡迎指正。