关于hibernate中双向外键关联one-to-one的property-ref=""的问题

大家都知道hibernate中的one-to-one映射主要有两种策略,(1)一对一主键关联(单向和双向)。(2)一对一外键映射(单项和双向)。本文主要讲解一下,一对一外键映射中的双向问题,在此前先通过一个实例了解。

person和idCard,是一种一对一的关系,其中

[color=red]t_person表[/color]
id name idCard(unique)
1 张三
2 王五 1

其中王五是没有idcard,这也符合现实中的,有些人是没有身份证的。
[color=red]t_idCard表[/color]
id cardNo
1 11111111111111


实体类:
[b] IdCard[/b]
package com.bjpowernode.hibernate;

public class IdCard {

private int id;

private String cardNo;

private Person person;

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getCardNo() {
return cardNo;
}

public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}


}

[b]Person[/b]
package com.bjpowernode.hibernate;

public class Person {

private int id;

private String name;

private IdCard idCard;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public IdCard getIdCard() {
return idCard;
}

public void setIdCard(IdCard idCard) {
this.idCard = idCard;
}
}

(3)配置文件
[b]IdCard的:[/b]
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.bjpowernode.hibernate">
<class name="IdCard" table="t_idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
<one-to-one name="person" class="Person" />
</class>
</hibernate-mapping>

[b] Person的:[/b]

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.bjpowernode.hibernate">
<class name="Person" table="t_person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="idCard" cascade="all" class="IdCard"
unique="true" column="card_ID" />
</class>
</hibernate-mapping>
(3)
向t_person中插入数据:
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();

Person person = new Person();
person.setName("张三");

session.save(person);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
结果如下:
mysql> select * from t_person;
+----+------+---------+
| id | name | card_ID |
+----+------+---------+
| 1 | 张三 | NULL |
+----+------+---------+
1 row in set (0.00 sec)

mysql> select * from t_idcard;
Empty set (0.00 sec)

在插入数据:
public void testSave2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();

IdCard idCard = new IdCard();
idCard.setCardNo("1111111111");
session.save(idCard);

Person person = new Person();
person.setName("王五");
//建立关联
person.setIdCard(idCard);

session.save(person);

session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
数据库中的结果如下:
mysql> select * from t_person;
+----+------+---------+
| id | name | card_ID |
+----+------+---------+
| 1 | 张三 | NULL |
| 2 | 王五 | 1 |
+----+------+---------+
2 rows in set (0.00 sec)

mysql> select * from t_idcard;
+----+------------+
| id | cardNo |
+----+------------+
| 1 | 1111111111 |
+----+------------+
1 row in set (0.00 sec)
(4)加载数据,这样的话就可以从person的一端加载到idCard,
如下:
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Person person = (Person)session.load(Person.class, 2);
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);
}
}
结果如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_, person0_.card_ID as card3_0_0_ from t_person person0_ where person0_.id=?
person.name=王五
Hibernate: select idcard0_.id as id1_1_, idcard0_.cardNo as cardNo1_1_, person1_.id as id0_0_, person1_.name as name0_0_, person1_.card_ID as card3_0_0_ from t_idCard idcard0_ left outer join t_person person1_ on idcard0_.id=person1_.id where idcard0_.id=?
person.cardNo=1111111111 这样的就找到了person对应的idcard,那能不能有idCard找到person呢?

public void testLoad2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//
IdCard idCard = (IdCard)session.load(IdCard.class, 1);
System.out.println("idCard.cardNo=" + idCard.getCardNo());
System.out.println("idCard.person.name=" + idCard.getPerson().getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
结果如下:
Hibernate: select idcard0_.id as id1_1_, idcard0_.cardNo as cardNo1_1_, person1_.id as id0_0_, person1_.name as name0_0_, person1_.card_ID as card3_0_0_ from t_idCard idcard0_ left outer join t_person person1_ on idcard0_.id=person1_.id where idcard0_.id=?
idCard.cardNo=1111111111
idCard.person.name=张三
[color=red]结果对吗?
肯定不对,idCard.cardNo=1111111111这是王五的idCard,怎么查出来张三的呢?原因在于:

idCard的配置文件问题:
应该在idCard的配置文件的<one-to-one name="person" class="Person" />
修改为<one-to-one name="person" class="Person" property-ref="idCard"/>
因为:如果不修改则idCard会根据自己的id和person中的id比较(因为one-to-one是通过id查找到的),这样是不符合要求的,因为我们t_idcard中的id和t_person中 Card_ID相比较,这样的话可以通过
property-ref="idCard" 的设置找到t_person表中Card_ID和它作比较找到我们要找的数据。 [/color]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值