hibernate一对一唯一外键关联映射(单向关联Person---->IdCard) 一对唯一外键关联映射是多对一关联映射的特例: public class Person { private int id; private String name; private IdCard idCard; // 在多的一方加入一个外键,数据库中增加一个字锻 ------------------------------------------------------------------------- <hibernate-mapping> < class name="com.bjsxt.hibernate.Person" table="t_person"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <many-to-one name="idCard" unique="true"/> </ class> </hibernate-mapping> ------------------------------------------------------------------------- 可以采用<many-to-one>标签,指定多的一端的unique= true,这样就限制了多的一端的多重性为一 通过这种手段映射一对一唯一外键关联 ------------------------------------------------------------------------- 导出表语句: create table t_idcard (id integer not null auto_increment, cardNo varchar(255), primary key (id)) create table t_person (id integer not null auto_increment, name varchar(255), idCard integer unique, primary key (id)) alter table t_person add index FK785BED80539D4B66 (idCard), add constraint FK785BED80539D4B66 foreign key (idCard) references t_idcard (id) ------------------------------------------------------------------------- mysql> use 07hibernate_one2one_ufk_1; Database changed mysql> desc t_person; +--------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | idCard | int(11) | YES | UNI | NULL | | +--------+--------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) mysql> desc t_idcard; +--------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | cardNo | varchar(255) | YES | | NULL | | +--------+--------------+------+-----+---------+----------------+ 2 rows in set (0.00 sec) TestSave1:由于没有设置cascade="all",或者你只保存了多方,没有保存一方,则会抛出异常信息:org.hibernate.TransientObjectException org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.bjsxt.hibernate.IdCard TestSave1: Hibernate: insert into t_idcard (cardNo) values (?) Hibernate: insert into t_person (name, idCard) values (?, ?) mysql> select * FROM t_person; +----+------+--------+ | id | name | idCard | +----+------+--------+ | 2 | 菜10 | 1 | +----+------+--------+ 1 row in set (0.00 sec) mysql> select * FROM t_idcard; +----+----------------+ | id | cardNo | +----+----------------+ | 1 | 88888888888888 | +----+----------------+ 1 row in set (0.00 sec) TestLoad: Hibernate: select person0_.id as id1_0_, person0_.name as name1_0_, person0_.idCard as idCard1_0_ from t_person person0_ where person0_.id=? person.name=菜10 Hibernate: select idcard0_.id as id0_0_, idcard0_.cardNo as cardNo0_0_ from t_idcard idcard0_ where idcard0_.id=? idCard.cardNo=88888888888888 ------------------------------------------------------ package com.bjsxt.hibernate; import org.hibernate.Session; import junit.framework.TestCase; public class One2OneTest extends TestCase { public void testSave1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); IdCard idCard = new IdCard(); idCard.setCardNo("88888888888888"); Person person = new Person(); person.setName("猪八戒"); person.setIdCard(idCard); // 不能成功保存,因为IdCard是Transient状态 session.save(person); session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } public void testSave2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); IdCard idCard = new IdCard(); idCard.setCardNo("88888888888888");
//先保存一方,再保存多方,OK! session.save(idCard); Person person = new Person(); person.setName("菜10"); person.setIdCard(idCard); session.save(person); session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } public void testLoad1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); //由于 testSave1()抛出异常,所以数据库中的记录 id=2 Person person = (Person)session.load(Person. class, 2); System.out.println("person.name=" + person.getName()); System.out.println("idCard.cardNo=" + person.getIdCard().getCardNo()); session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } }