一对一映射分为单向的和双向的
单向:主键关联映射,唯一外键关联映射
双向:主键关联映射,唯一外键关联映射
单向主键关联映射,一对一单向主键关联时没有抛出TransientObjectException,是由一对一关联映射的特性决定的,它必须先保存关联对象,这种保存hibernate它给你做了,它默认了cascade属性.
此种关联映射有一定的缺点:单向一对一主键关联实际上限制很多,因为你只有IdCard插入了那才能有这个Person.
原理:一对一关联映射原理:让两个实体的主键一样,这样就不需要加入多余的字段了
对象模型如下:
public class IdCard {
private int id;
private String cardNo;
}
public class Person {
private int id;
private String name;
private IdCard idCard;
}
映射如下:
IdCard.hbm.xml
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Person" table="t_person">
<id name="id">
<!-- 采用foreign生成策略,forgeign会取得关联对象的标识 -->
<generator class="foreign">
<!-- property只关联对象 -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!--
one-to-one指示hibernate如何加载其关联对象,默认根据主键加载
也就是拿到关系字段值,根据对端的主键来加载关联对象
constrained="true表示,当前主键(person的主键)还是一个外键
参照了对端的主键(IdCard的主键),也就是会生成外键约束语句
-->
<one-to-one name="idCard" constrained="true"/>
</class>
</hibernate-mapping>
测试 添加和加载如下:
public void testSave1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
IdCard idCard = new IdCard();
idCard.setCardNo("1111111111111111");
Person person = new Person();
person.setName("张三");
//建立关联
person.setIdCard(idCard);
//没有抛出TransientObjectException
//是由一对一关联映射的特性决定的,它必须先保存关联对象IdCard
//这样它采用foreign映射策略才能取得关联对象的标识
//也就是它默认了cascade属性,注意对比多对一映射
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("1111111111111111");
Person person = new Person();
person.setName("张三");
//建立关联
person.setIdCard(idCard);
//只能将IdCard保存,不能将Person保存
//因为关系的维护端在Person端,IdCard不知道Person的存在,总结:维护端不在自己这一端的时候并不能知道对方的存在的.
session.save(idCard);
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();
Person person = (Person)session.load(Person.class, 1);
System.out.println("person.name=" + person.getName());
System.out.println("person.cardNo=" + person.getIdCard().getCardNo());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}