Hinernate Ont to One Mappting
一对一关系有两种形式:
1. 共享主键形式
2. 唯一外键形式
此处以2为例,论坛的主题对应一个作者,因此为唯一外键方式的一对一关联。
1、新建数据库表如下:
CREATE TABLE `author` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) default NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `topic` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) default NULL,
`user_id` int(11) default NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `author` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) default NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `topic` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) default NULL,
`user_id` int(11) default NULL,
PRIMARY KEY (`id`)
);
2 生成映射文件:
(1)Topic.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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.zyl.hibernate.Topic" table="topic"
catalog="hibernatemap">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="50" />
</property>
<many-to-one lazy="false" name="author" class="com.zyl.hibernate.Author" column="user_id" unique="true"/>
</class>
</hibernate-mapping>
(2)Author.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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.zyl.hibernate.Author" table="author" catalog="hibernatemap">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="50" />
</property>
</class>
</hibernate-mapping>
3 java类文件:
(1)Author.Java
package com.zyl.hibernate;
/**
*AuthorgeneratedbyMyEclipsePersistenceTools
*/
publicclass Author implements java.io.Serializable {
// Fields
private Integer id;
private String name;
// Constructors
/**defaultconstructor*/
public Author() {
}
/**fullconstructor*/
public Author(String name) {
this.name = name;
}
// Property accessors
public Integer getId() {
returnthis.id;
}
publicvoid setId(Integer id) {
this.id = id;
}
public String getName() {
returnthis.name;
}
publicvoid setName(String name) {
this.name = name;
}
public String toString() {
return"id:" + getId() + "/t name:" + getName();
}
publicboolean equals(Object other) {
if (!(other instanceof Author))
returnfalse;
Author castOther = (Author) other;
returnthis.getId().equals(castOther.getId());
}
publicint hashCode() {
return getId().hashCode();
}
}
(2)Topic.java
package com.zyl.hibernate;
/**
*TopicgeneratedbyMyEclipsePersistenceTools
*/
publicclass Topic implements java.io.Serializable {
// Fields
private Integer id;
private String name;
private Author author;
// Constructors
/**defaultconstructor*/
public Topic() {
}
/**fullconstructor*/
public Topic(String name, Author author) {
this.name = name;
this.author = author;
}
// Property accessors
public Integer getId() {
returnthis.id;
}
publicvoid setId(Integer id) {
this.id = id;
}
public String getName() {
returnthis.name;
}
publicvoid setName(String name) {
this.name = name;
}
public String toString() {
return"id:" + getId() + "/t topic name:" + getName();
}
publicboolean equals(Object other) {
if (!(other instanceof Topic))
returnfalse;
Topic castOther = (Topic) other;
returnthis.getId().equals(castOther.getId());
}
publicint hashCode() {
return getId().hashCode();
}
public Author getAuthor() {
returnauthor;
}
publicvoid setAuthor(Author author) {
this.author = author;
}
}
3、建立测试用例。
package com.zyl.hibernate;
package com.zyl.hibernate;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import sessionFactory.HibernateSessionFactory;
publicclass OneToOneTest {
Session sess;
Transaction tx;
AuthorDAO adao;
TopicDAO tdao;
publicvoid insertTopic(Topic topic, int userID) {
tdao = new TopicDAO();
try {
sess = HibernateSessionFactory.getSession();
tx = sess.beginTransaction();
// 新建一个author对象,并把作者id置入该对象里。
Author author = new Author();
author.setId(userID);
// 新建一个topic对象,设置用户名和把author对象set进去。
topic.setAuthor(author);
// 因为只是插入一个话题,并不必在author表中插入一条记录,所以只需save(topic)
tdao.save(topic);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
System.out.println(e.toString());
} finally {
sess.close();
}
}
publicvoid insertAuthor(Author author) {
adao = new AuthorDAO();
try {
sess = HibernateSessionFactory.getSession();
tx = sess.beginTransaction();
adao.save(author);
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
System.out.println(e.toString());
} finally {
sess.close();
}
}
public Topic query(int id) {
tdao = new TopicDAO();
Topic topic = null;
try {
sess = HibernateSessionFactory.getSession();
topic = tdao.findById(id);
} catch (Exception e) {
e.printStackTrace();
} finally {
sess.close();
}
return topic;
}
publicstaticvoid main(String[] args) {
OneToOneTest app = new OneToOneTest();
// 测试插入作者
// Author author = new Author();
// author.setName("张");
// app.insertAuthor(author);
// System.out.println("测试插入作者");
// 测试插入主题
// Topic topic = new Topic();
// topic.setName("meimeia");
// app.insertTopic(topic, 1);
// System.out.println("测试插入主题");
// 测试查询主题
Topic topic = app.query(1);
System.out.println(topic.getAuthor().getName());
System.out.println(" 测试查询主题");
}
}
测试中出现的问题:
没有把映射文件中的 Set 中加入lazy="false"报错:
"org.hibernate.LazyInitializationException: could not initialize proxy"延迟抓取出的错,hb3对many-to-one的默认处理是lazy = "proxy",
把所有many-to-one,one-to-one都加上lazy="false"
测试成功。