一对一外键关联,实际上就是多对一的特例。只要将原来的many-to-one加上unique="true"属性。
参考自熔岩:http://lavasoft.blog.51cto.com/62575/39279
Address11fk.java
private int addressId;
private String detailAddress;
Person11fk.java
private int personId;
private String personName;
private int age;
private Address11fk address11fk;
表结构:
-- 一对一单向外键关联人员表,人员表的外键address_id关联地址表的address_id
DROP TABLE IF EXISTS person_11fk;
CREATE TABLE person_11fk (
person_id int(11) PRIMARY KEY auto_increment,
person_name varchar(255),
age int(3),
address_id int(11) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 一对一单向外键关联地址表
DROP TABLE IF EXISTS address_11fk;
CREATE TABLE address_11fk (
address_id int(11) PRIMARY KEY auto_increment,
detail_address varchar(255)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE person_11fk ADD CONSTRAINT fk_11fk_addressid FOREIGN KEY (address_id) REFERENCES address_11fk(address_id);
-- SELECT * FROM person_11fk;
-- SELECT * FROM address_11fk;
Address11fk.hbm.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.ack.hibernateMapping.entity.Address11fk" table="address_11fk">
<id name="addressId" column="address_id">
<generator class="identity"/>
</id>
<property name="detailAddress" column="detail_address"/>
</class>
</hibernate-mapping>
Person11fk.hbm.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.ack.hibernateMapping.entity.Person11fk" table="person_11fk">
<id name="personId" column="person_id">
<generator class="identity"/>
</id>
<property name="personName" column="person_name"/>
<property name="age"/>
<many-to-one name="address11fk" column="address_id" unique="true"/>
</class>
</hibernate-mapping>
在hibernate.cfg.xml中加入实体类映射文件的引入。
测试类
public class Test_pa_11fk_single {
public static void main(String[] args) {
Person11fk p1 = new Person11fk();
p1.setPersonName("陈三");
Address11fk add1 = new Address11fk();
add1.setDetailAddress("丽水市莲都区");
p1.setAddress11fk(add1);
Session session = HibernateUtil.getCurrentSession();
session.beginTransaction();
session.save(add1);
session.save(p1);
session.getTransaction().commit();
}
}
先save add1,再save p1,sql语句如下:
insert into address_11fk(detail_address) values(?)
insert into person_11fk(person_name, age, address_id) values(?, ?, ?)
先save p1,再save add1,sql语句如下:
insert into person_11fk(person_name, age, address_id) values(?, ?, ?)
insert into address_11fk(detail_address) values(?)
update person_11fk set person_name=?,age=?,address_id=? where person_id=?
只save add1,sql语句如下:
insert into address_11fk(detail_address) values(?)
只save p1,sql语句如下:
insert into person_11fk(person_name, age, address_id) values(?, ?, ?)
但会报错:org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.ack.hibernate.hibernateMapping.entity.Address11fk,所以数据也无法提交。
与Hibernate之对象关系映射01一对一单向关联配置区别在于关联Person11fk配置与Person的差别,一个生成中间表,一个用外键关联。