hibernate one-to-one

[from] http://bravefly.iteye.com/blog/232418

 

关键字: one-to-one

one-to-one在hibernate中可以用来作为两张表之间的主键关联,这也是hibernate中主键关联的一种用法,这样在一张表中的ID,在生成另外一张表的同时回自动插入到相应的ID字段中去,相应的XML文件设置比较简单,举例如下:

<!-- 建立一对一的到Address的映射,这个是写在User的XML配置文件中的 -->
<!-- 相应的User bean(PO)中也要添加属性 com.xx.Address address-->
Java代码 复制代码
  1. <one-to-one name= "address"  cascade= "all"   class = "com.xx.Address" />  
<one-to-one name="address" cascade="all" class="com.xx.Address"/>

<!-- cascade的属性设置不再重复了,可以查看hibernate文档 -->

<!-- 建立一对一的到User的映射,这个是写在Address的XML配置文件中的 -->
<!-- 相应的Address bean(PO)中也要添加属性 com.xx.User user--> -->
Java代码 复制代码
  1. <one-to-one name= "user"   class = "com.xx.User"  constrained= "true" />  
<one-to-one name="user" class="com.xx.User" constrained="true"/>


constrained="true" 告诉Hibernate Address的PK还应该是一个FK,这个FK引用User的PK。为了在Address中使用User中的主键ID值,我们需要设置Address中 的主键生成规则,如下所示,采用foreign关键字
Java代码 复制代码
  1. <id column= "ID"  name= "id"  type= "long"  unsaved-value= "0" >   
  2.    <generator class = "foreign" >  
  3.      <param name="property" >user</param>    
  4.    </generator>  
  5. </id>  
   <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的映射关系。 unsaved-value是表示一个对象是新的还是旧的,如果unsaved-value=none 那么就是新的,就会被insert到数据库中,如 果unsaved-value=any 就是说明对象是从数据库中load的,被update到数据库中

上面的过程都很简单,下面我来说说这里需要注意的地方:

1. 在设置属性ID的时候必须注意字段的长度,如笔者这样使用oracle的sequence来生成ID,其长度有14位之长,则应选择hibernate类型long,对应的实体中应选择Long,这样不会出现溢出的情况。


2. 在测试的时候必须要注意这两张表之间因为已经存在了一对一的关系,所以我们不能只写
user.setAddress(address);
而忽略了
address.setUser(user);
这样在做插入的时候会报出attempted to assign id from null one-to-one property: address的错误,这一点初学者会经常犯,笔者也是其中之一。


3. 如果不写cascade="all"或者写成cascade="none"的话,即使你写了
user.setAddress(address);
address.setUser(user);
也不会发生任何事情,只有user会被存储。

以上是一点点小经验,如果有不对的地方欢迎指正。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章