hibernate多对一关联配置
2014-09-04 16:43
429 查看
实体是Employee和Department,它们之间是多对一的关系。
Department类:
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
public class Department {
private int id;
private String name;
public Department() {
}
public Department(String name) {
this.name = name;
}
// getters and setters are omitted
}
Employee类:
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
public class Employee {
private int id;
private String name;
private Department department;
public Employee() {
}
public Employee(String name) {
this.name = name;
}
// getters and setters are omitted
Department.hbm.xml:
Xml代码
![](http://czj4451.iteye.com/images/icon_star.png)
<hibernate-mapping
package="com.john.myhibernate.domain">
<class name="Department">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="20" not-null="true"/>
</class>
</hibernate-mapping>
Employee.hbm.xml:
Xml代码
![](http://czj4451.iteye.com/images/icon_star.png)
<hibernate-mapping package="com.john.myhibernate.domain">
<class name="Employee">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="20" not-null="true"/>
<many-to-one name="department" column="department_id" class="Department" fetch="select"/>
</class>
</hibernate-mapping>
many-to-one没有inverse属性,因为关系的维护是many的一方,不可能放弃对关系的维护。
many-to-one的lazy属性有三个取值:false, proxy, no-proxy。
1. 测试cascade属性:
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
public void testSaveCascade() {
Session s = null;
Transaction tx = null;
Department depart = new Department();
depart.setName("FCI");
Employee em1 = new Employee("John");
em1.setDepartment(depart);
Employee em2 = new Employee("Lucy");
em2.setDepartment(depart);
try {
s = HibernateUtil.getSession();
tx = s.beginTransaction();
s.save(em1);
s.save(em2);
tx.commit();
} catch (HibernateException e) {
tx.rollback();
e.printStackTrace();
} finally {
if (s != null)
s.close();
}
}
结果是报org.hibernate.TransientObjectException异常,因为没有保存Department实例。
可以加cascade属性,解决问题:
Xml代码
![](http://czj4451.iteye.com/images/icon_star.png)
<many-to-one name="department" column="department_id" class="Department" fetch="select" cascade="save-update"/>
2. 测试fetch
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
Session s = null;
s = HibernateUtil.getSession();
Employee em = (Employee) s.get(Employee.class, 2);
System.out.println(em.getName());
System.out.println(em.getDepartment());
查询语句如下:
Hibernate: select employee0_.id as id1_0_, employee0_.name as name1_0_, employee0_.department as department1_0_, employee0_.skill as skill1_0_, employee0_.sell
as sell1_0_, employee0_.type as type1_0_ from Employee employee0_ where employee0_.id=?
Hibernate: select department0_.id as id0_0_, department0_.name as name0_0_ from Department department0_ where department0_.id=?
因为fetch设置为select,所以对每个实体,都分别用一个SELECT语句
如果把fetch设置为join,也就是连表查询,只使用一个SELECT语句。如下:
Hibernate: select employee0_.id as id1_1_, employee0_.name as name1_1_, employee0_.department as department1_1_, employee0_.skill as skill1_1_, employee0_.sell
as sell1_1_, employee0_.type as type1_1_, department1_.id as id0_0_, department1_.name as name0_0_ from Employee employee0_ left outer join Department department1_ on employee0_.department=department1_.id where employee0_.id=?
3. 测试lazy
当fetch为select时,设置lazy为proxy或者no-proxy。
Xml代码
![](http://czj4451.iteye.com/images/icon_star.png)
<many-to-one name="department" column="department_id" class="Department" fetch="select" cascade="save-update" lazy="no-proxy"/>
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
Session s = null;
s = HibernateUtil.getSession();
Employee em = (Employee) s.get(Employee.class, 2);
s.close();
System.out.println(em.getName());
System.out.println(em.getDepartment());
结果是报org.hibernate.LazyInitializationException异常。
因为fetch为select,而且lazy为proxy或者no-proxy,所以开始仅仅查询Employee,当需要用SELECT语句查询Department时,Session已经关闭。
解决办法:
1. 设置lazy为false,hibernate会第一时间把Employee和Department查询出来。
如果fetch为select,使用两个SELECT查询语句。
如果fetch为join,使用一个SELECT连表查询语句。
2. 设置fetch为join,这时不管lazy的取值,hibernate会进行连表查询,把两个实体都查询出来。
Department类:
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
public class Department {
private int id;
private String name;
public Department() {
}
public Department(String name) {
this.name = name;
}
// getters and setters are omitted
}
Employee类:
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
public class Employee {
private int id;
private String name;
private Department department;
public Employee() {
}
public Employee(String name) {
this.name = name;
}
// getters and setters are omitted
Department.hbm.xml:
Xml代码
![](http://czj4451.iteye.com/images/icon_star.png)
<hibernate-mapping
package="com.john.myhibernate.domain">
<class name="Department">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="20" not-null="true"/>
</class>
</hibernate-mapping>
Employee.hbm.xml:
Xml代码
![](http://czj4451.iteye.com/images/icon_star.png)
<hibernate-mapping package="com.john.myhibernate.domain">
<class name="Employee">
<id name="id">
<generator class="native"/>
</id>
<property name="name" length="20" not-null="true"/>
<many-to-one name="department" column="department_id" class="Department" fetch="select"/>
</class>
</hibernate-mapping>
many-to-one没有inverse属性,因为关系的维护是many的一方,不可能放弃对关系的维护。
many-to-one的lazy属性有三个取值:false, proxy, no-proxy。
1. 测试cascade属性:
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
public void testSaveCascade() {
Session s = null;
Transaction tx = null;
Department depart = new Department();
depart.setName("FCI");
Employee em1 = new Employee("John");
em1.setDepartment(depart);
Employee em2 = new Employee("Lucy");
em2.setDepartment(depart);
try {
s = HibernateUtil.getSession();
tx = s.beginTransaction();
s.save(em1);
s.save(em2);
tx.commit();
} catch (HibernateException e) {
tx.rollback();
e.printStackTrace();
} finally {
if (s != null)
s.close();
}
}
结果是报org.hibernate.TransientObjectException异常,因为没有保存Department实例。
可以加cascade属性,解决问题:
Xml代码
![](http://czj4451.iteye.com/images/icon_star.png)
<many-to-one name="department" column="department_id" class="Department" fetch="select" cascade="save-update"/>
2. 测试fetch
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
Session s = null;
s = HibernateUtil.getSession();
Employee em = (Employee) s.get(Employee.class, 2);
System.out.println(em.getName());
System.out.println(em.getDepartment());
查询语句如下:
Hibernate: select employee0_.id as id1_0_, employee0_.name as name1_0_, employee0_.department as department1_0_, employee0_.skill as skill1_0_, employee0_.sell
as sell1_0_, employee0_.type as type1_0_ from Employee employee0_ where employee0_.id=?
Hibernate: select department0_.id as id0_0_, department0_.name as name0_0_ from Department department0_ where department0_.id=?
因为fetch设置为select,所以对每个实体,都分别用一个SELECT语句
如果把fetch设置为join,也就是连表查询,只使用一个SELECT语句。如下:
Hibernate: select employee0_.id as id1_1_, employee0_.name as name1_1_, employee0_.department as department1_1_, employee0_.skill as skill1_1_, employee0_.sell
as sell1_1_, employee0_.type as type1_1_, department1_.id as id0_0_, department1_.name as name0_0_ from Employee employee0_ left outer join Department department1_ on employee0_.department=department1_.id where employee0_.id=?
3. 测试lazy
当fetch为select时,设置lazy为proxy或者no-proxy。
Xml代码
![](http://czj4451.iteye.com/images/icon_star.png)
<many-to-one name="department" column="department_id" class="Department" fetch="select" cascade="save-update" lazy="no-proxy"/>
Java代码
![](http://czj4451.iteye.com/images/icon_star.png)
Session s = null;
s = HibernateUtil.getSession();
Employee em = (Employee) s.get(Employee.class, 2);
s.close();
System.out.println(em.getName());
System.out.println(em.getDepartment());
结果是报org.hibernate.LazyInitializationException异常。
因为fetch为select,而且lazy为proxy或者no-proxy,所以开始仅仅查询Employee,当需要用SELECT语句查询Department时,Session已经关闭。
解决办法:
1. 设置lazy为false,hibernate会第一时间把Employee和Department查询出来。
如果fetch为select,使用两个SELECT查询语句。
如果fetch为join,使用一个SELECT连表查询语句。
2. 设置fetch为join,这时不管lazy的取值,hibernate会进行连表查询,把两个实体都查询出来。
相关文章推荐
- hibernate.cfg.xml关联Oracle数据库的配置
- hibernate多对一外键关联之annotation配置
- hibernate学习(二)list与iterator区别,一对多双向关联配置
- hibernate学习——hibernate配置与关联总结
- hibernate.cfg.xml关联Oracle数据库的配置
- 一个典型的Hibernate多对一关联配置
- 【转】hibernate annotation方式配置实体关联关系,解决关联外键数据不存在时抛出异常的问题
- Hibernate多对多双向关联(Annotation配置)
- Hibernate多对一双表关联配置属性理解
- hibernate中配置非主键关联(单向一对多)
- Hibernate的一些关联关键字的配置略谈
- Hibernate一对一主键双向关联映射(xml配置)
- Hibernate复合主键作为外键在关联映射中的配置方法
- Hibernate多对多双向关联(Annotation配置)
- Hibernate注解配置N:N关联
- hibernate表关联的各种配置
- Hibernate中配置双向多对多关联
- Hibernate注解配置1:1关联
- Hibernate联合主键关联(Annotation配置)
- Hibernate学习09---基于XML配置的一对一单向外键关联