`

Hibernate 多对一关联配置

阅读更多
实体是Employee和Department,它们之间是多对一的关系。

Department类:
public class Department {
	private int id;
	private String name;

	public Department() {
	}
	public Department(String name) {
		this.name = name;
	}
	// getters and setters are omitted
}


Employee类:
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:
<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:
<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属性:
	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属性,解决问题:
<many-to-one name="department" column="department_id" class="Department" fetch="select" cascade="save-update"/>


2. 测试fetch
	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。
<many-to-one name="department" column="department_id" class="Department" fetch="select" cascade="save-update" lazy="no-proxy"/>

	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会进行连表查询,把两个实体都查询出来。
分享到:
评论
2 楼 Hibernate1 2016-08-04  
讲解的很不错,收益了。感谢发表者;
1 楼 5dyoyo 2014-07-08  
[img][list]
[*]

[/list][/img]

相关推荐

    hibernate多对多关联映射

    在Java的持久化框架Hibernate中,多对多关联映射是一种常见的关系数据库模型映射方式,用于处理两个实体之间存在多个实例互相关联的情况。本文将深入探讨Hibernate如何实现多对多关联映射,并通过实际例子解析相关...

    hibernate多对一关联demo

    【标题】:“Hibernate多对一关联demo” 在Java开发中,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作。本教程将详细解释如何在Hibernate中实现多对一的关联关系,以及如何通过一个实际的示例...

    hibernate一对一关联关系

    在实体类之间,Hibernate支持多种关联关系,包括一对一(One-to-One)、一对多(One-to-Many)和多对多(Many-to-Many)。本资源主要探讨的是“hibernate一对一关联关系”。 一对一关联关系在现实世界中很常见,...

    hibernate多对一单向关联关系实现源码

    在Java的持久化框架Hibernate中,多对一(ManyToOne)关联关系是一种常见的对象关系映射(ORM)场景。这种关系通常出现在一个实体类拥有多条与另一个实体类相关的记录,而另一个实体类可能只有一条对应的记录。例如...

    Hibernate双向一对一关联映射(注解版)

    本主题聚焦于“Hibernate双向一对一关联映射”的注解实现,这是一种高级的数据库设计模式,用于处理两个实体之间一对一的关系。 在Hibernate中,一对一关联映射分为单向和双向。单向一对一映射通常涉及一个实体持有...

    hibernate多对一关联关系

    在Java的持久化框架Hibernate中,"多对一"关联关系是一种常见的对象关系映射(ORM)设计,它表示一个实体(子项)可以与多个其他实体(父项)相关联,而每个父项可能被多个子项引用。在数据库层面,这通常对应于一个...

    hibernate 多对一映射关联配置

    本文将深入探讨Hibernate中的多对一映射关联配置,并结合具体的文档心得进行讲解。 首先,我们要了解多对一映射的基本概念。在数据库设计中,如果一个表(实体A)的某一列是另一个表(实体B)的主键,那么就存在...

    hibernate多对多关联映射(单项关联)

    在Java的持久化框架Hibernate中,多对多关联映射是一种常见的关系模型,它用于处理两个实体类之间存在多个对应关系的情况。这篇博客"hibernate多对多关联映射(单项关联)"深入探讨了如何在Hibernate中实现这种映射...

    hibernate一对多关联映射(单向关联)

    这篇博客文章“hibernate一对多关联映射(单向关联)”将深入讲解如何配置和使用这种映射关系。 在单向关联中,只有一个实体知道另一个实体的存在,也就是说,只有父实体("一"的一端)有对子实体("多"的一端)的...

    Hibernate一对多关联映射(注解)

    本篇主要探讨的是Hibernate中的一对多关联映射,它允许一个实体对象对应数据库表中的多个行。在实际业务场景中,这种映射模式非常常见,例如一个用户可以拥有多个订单,一个部门可以包含多个员工等。 首先,我们来...

    Hibernate多表关联配置及错误解决方法

    在处理多表关联时,Hibernate提供了多种关联类型,包括一对一(OneToOne),多对一(ManyToOne),一对多(OneToMany)和多对多(ManyToMany)。本文将详细介绍这些关联配置以及如何解决可能出现的错误。 **一对一关联...

    hibernate3.2(六)多对一关联映射

    总结,本文详细介绍了在Hibernate 3.2中实现多对一关联映射的步骤,包括XML和注解方式的配置、外键策略、加载策略以及级联操作。理解并熟练掌握这些概念对于有效利用Hibernate进行数据库操作和优化应用性能具有重要...

    Hibernate ORM - 一对多双向关联关系

    描述部分为空,但我们可以根据标题推测,这篇博客可能详细解释了如何在Hibernate中配置和管理这种一对多双向关联,包括XML配置、注解方式,以及如何在代码中进行操作和查询。 **Hibernate ORM简介** Hibernate是一...

    hibernate一对多、多对一、一对一、多对多配置实例

    本文将深入探讨Hibernate中的一对多、多对一、一对一以及多对多四种关系映射的配置实例,帮助开发者更好地理解和运用这些关系。 ### 一对多关系(One-to-Many) 在数据库设计中,一对多关系是最常见的一种关联,...

    hibernate多对多双向关联

    "hibernate_many2many_2"这个文件名可能是指一个关于Hibernate多对多关联的示例或教程的第二部分,可能包含配置文件、Java实体类、映射文件以及相关的测试代码。 **详细知识点:** 1. **实体类定义**:在Hibernate...

    hibernate多对一关联映射

    -- 多对一关联配置 --&gt; &lt;/hibernate-mapping&gt; ``` 4. **注解映射:** 如果使用注解进行映射,可以在Department类中添加@OneToOne注解: ```java @Entity public class Department { @Id @GeneratedValue...

    Hibernate一对一主键关联映射(单向关联)

    在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是常见的关系映射方式之一,尤其在处理两个实体之间存在唯一对应关系时非常有用。本篇将重点讲解如何实现一对一主键关联映射的单向关联,并通过一个...

    hibernate一对多,多对一,一对多双向关联

    由于只给出了"hibernate_003"这个文件名,我们无法直接获取具体信息,但可以猜测这是一个系列教程的一部分,"003"可能是表示序列号,表示这是关于Hibernate关联关系的第三个主题或者第三部分。 **详细知识点:** 1...

    Hibernate 多对多关联

    在Java的持久化框架Hibernate中,多对多(Many-to-Many)关联是一种常见的数据库关系...在实际开发过程中,理解并熟练掌握Hibernate的多对多关联配置和操作方式是非常重要的,它能帮助你构建出高效、稳定的持久化层。

    Hibernate 一对一关联查询.docx

    在Java的持久化框架Hibernate中,一对一(One-to-One)关联查询是一种常见的关系映射方式,用于表示两个实体之间一对一的依赖关系。这种关联通常在数据库中通过外键或者主键来实现。本文将深入探讨基于外键的一对一...

Global site tag (gtag.js) - Google Analytics