Hibernate一對一雙向關聯(外部索引鍵關聯)用法小結,hibernate一對一

來源:互聯網
上載者:User

Hibernate一對一雙向關聯(外部索引鍵關聯)用法小結,hibernate一對一

這幾天在改一個項目源碼,遇到一個問題坑了很久。情境如下(註:此處是借鑒網路上的例子,並不是自己的實驗環境):

一夫一妻制——比如夫妻關係的兩張資料表,一個是wif表,一個是husban表,其資料表資訊如下:

CREATE TABLE `wife` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `name` varchar(50) NOT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8CREATE TABLE `husband` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `name` varchar(50) NOT NULL,  `wifeid` int(11) DEFAULT NULL,  PRIMARY KEY (`id`),  KEY `fk_wife` (`wifeid`),  CONSTRAINT `fk_wife` FOREIGN KEY (`wifeid`) REFERENCES `wife` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8

即一個wife表和一個husband表,這裡wife表為基表,husband表中的wifeid依賴於wife的主鍵id。

下面是相應的POJO:

Wife:  1.package com.linys.model;  2.  3./** 4. * Wife entity. @author MyEclipse Persistence Tools 5. */  6.  7.public class Wife implements java.io.Serializable {  8.  9.    // Fields  10.  11.    /** 12.     *  13.     */  14.    private static final long serialVersionUID = 1L;  15.    private Integer id;  16.    private String name;  17.    private Husband husband;  18.    // Constructors  19.  20.    /** default constructor */  21.    public Wife() {  22.    }  23.  24.    /** minimal constructor */  25.    public Wife(String name) {  26.        this.name = name;  27.    }  28.  29.  30.    // Property accessors  31.  32.    public Integer getId() {  33.        return this.id;  34.    }  35.  36.    public void setId(Integer id) {  37.        this.id = id;  38.    }  39.  40.    public String getName() {  41.        return this.name;  42.    }  43.  44.    public void setName(String name) {  45.        this.name = name;  46.    }  47.  48.    public Husband getHusband() {  49.        return husband;  50.    }  51.  52.    public void setHusband(Husband husband) {  53.        this.husband = husband;  54.    }  55.  56.  57.}    Husband:   1.package com.linys.model;  2.  3./** 4. * Husband entity. @author MyEclipse Persistence Tools 5. */  6.  7.public class Husband implements java.io.Serializable {  8.  9.    // Fields  10.  11.    /** 12.     *  13.     */  14.    private static final long serialVersionUID = 1L;  15.    private Integer id;  16.    private Wife wife;  17.    private String name;  18.  19.    // Constructors  20.  21.    /** default constructor */  22.    public Husband() {  23.    }  24.  25.    /** minimal constructor */  26.    public Husband(String name) {  27.        this.name = name;  28.    }  29.  30.    /** full constructor */  31.    public Husband(Wife wife, String name) {  32.        this.wife = wife;  33.        this.name = name;  34.    }  35.  36.    // Property accessors  37.  38.    public Integer getId() {  39.        return this.id;  40.    }  41.  42.    public void setId(Integer id) {  43.        this.id = id;  44.    }  45.  46.    public Wife getWife() {  47.        return this.wife;  48.    }  49.  50.    public void setWife(Wife wife) {  51.        this.wife = wife;  52.    }  53.  54.    public String getName() {  55.        return this.name;  56.    }  57.  58.    public void setName(String name) {  59.        this.name = name;  60.    }  61.  62.}  

以上是基本的資料表映射。這時候假設我們需要一對一雙向關聯,即在儲存或者更新時,可以根據一個husband執行個體可以獲得其wife執行個體,也可根據wife執行個體去獲得一個husband執行個體。

一對一雙向關聯比較特殊,不像單向關聯,在hbm設定檔中僅僅使用one-to-one配置即可,這種情況下需要使用may-to-one和one-to-one來類比一一對應,既然是一一對應,所以在many-to-one的一段,要加上unique=true屬性,從而保證其唯一性。不要問我為什麼,這是Hibernate的機制吧,其實說到這裡,我對於Hibernate還不是很瞭解,如果有大神讀到希望可以指點一二。從項目經驗來看,如果不這麼做,在同時修改了這兩個實體,然後儲存到庫中時,總是報錯,錯誤資訊為session無法同步,或者外鍵id為NULL。使用了這樣的配置後,就沒有問題了。下面看二者的設定檔:

Wife.hbm.xml Java代碼   1.<?xml version="1.0" encoding="utf-8"?>  2.<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  3."http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  4.<!--   5.    Mapping file autogenerated by MyEclipse Persistence Tools  6.-->  7.<hibernate-mapping>  8.    <class name="com.linys.model.Wife" table="wife">  9.        <id name="id" type="java.lang.Integer">  10.            <column name="id" />  11.            <generator class="native" />  12.        </id>  13.        <property name="name" type="java.lang.String">  14.            <column name="name" length="50" not-null="true" />  15.        </property>  16.       <one-to-one name="husband" class="com.linys.model.Husband" property-ref="wife" cascade="all"/> 17.    </class>  18.</hibernate-mapping>   Husband.hbm.xml:1.<?xml version="1.0" encoding="utf-8"?>  2.<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  3."http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  4.<!--   5.    Mapping file autogenerated by MyEclipse Persistence Tools  6.-->  7.<hibernate-mapping>  8.    <class name="com.linys.model.Husband" table="husband">  9.        <id name="id" type="java.lang.Integer">  10.            <column name="id" />  11.            <generator class="native" />  12.        </id>  13.        <property name="name" type="java.lang.String">  14.            <column name="name" length="50" not-null="true" />  15.        </property>  16.        <may-to-one name="wife" class="com.linys.model.Wife" fetch="select"/>17.             <column name="wifeid" unique="true" not-null="true" />  18.        </many-to-one>  19.    </class>  20.</hibernate-mapping>  

外鍵所依賴的那個表的設定檔(wife)使用one-to-one,外鍵所在的表(husband)用many-to-one,但是要指定unique為true從而保證其唯一性。注意many這一端中的colum,配置的應該是外鍵所在表的外鍵列名,對應這裡也就是husband表中的“wifeid”,需要與資料庫中的資料表表中一致,切勿弄錯。

one-to-one:指定在Wife這個類中用於雙向關聯的屬性husband

property-ref: 在關聯對象中用於與本對象關聯的屬性。

注意:property-ref="wife"不能少,否則會造成查詢時關聯查詢失敗!


以上是實際經驗的總結,如有錯誤,歡迎指正。



相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.