Hibernate 在加载关联对象时有两种加载方式:
延迟装载——关联对象何时用何时装载 hibernate3.x 默认使用延迟装载
即时装载——装载对象时立即加载关联对象 hibernate2.x 默认使用即时装载
1.什么是延迟加载问题
首先我们来回顾之前我们封装的业务DAO
/** * 雇员实体 * 包括:雇员编号,雇员姓名,雇员所在部门(关联至部门表) * @author RoyAkon */ public class Employee implements java.io.Serializable { private Integer employeeId; private Department department; private String employeeName; //Geter and Seter.... }
/** * 业务DAO 继承自 BaseHibernateDAO * @author Administrator */ public class HrDAO extends BaseHibernateDAO { /** * 根据雇员编号取得雇员信息 * @param employeeId * @return */ public Employee getEmployeeById(Integer employeeId) { Employee employee = null; try { employee = (Employee)super.getSession().get(Employee.class, employeeId); } catch (Exception e) { e.printStackTrace(); } finally { super.closeSession(); } return employee; } }
当我们使用雇员数据时,会发生什么事情呢?
/** * 测试-输出关联对象内容 * @author Administrator */ public class Tester { public static void main(String[] args) { HrDAO dao = new HrDAO(); System.out.print(employee.getDepartment().getDepartmentName()); } }
Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed
大家会发现程序抛出上述的的运行期错误,因为延迟加载机制的存在导致了当要使用关联对象的内容时,Hibernate 去动态加载需要的内容,但是我们在DAO封装时已经将Session关闭了。无法动态加载导致异常。如果保持Session那不是会破坏封装吗?如何解决这个问题呢?
如何解决延迟加载的问题?
1.对象配置文件配置 lazy=”false”
在对象配置文件中 关联属性项中配置 lazy=”false” 项目表示了当前关联对象需要即时加载方式
<!-- Employee.hbm.xml 中对其关联属性 雇员所在部门配置 lazy="false" --> <many-to-one lazy="false" name="department" class="cn.net.royakon.entity.Department" fetch="select"> <column name="employee_department" not-null="true" /> </many-to-one>
2.DAO封装业务时编写代码要求加载关联对象
- 当业务DAO取得单个对象时
/** * 业务DAO 继承自 BaseHibernateDAO * @author Administrator */ public class HrDAO extends BaseHibernateDAO { /** * 根据雇员编号取得雇员信息 * @param employeeId * @return */ public Employee getEmployeeById(Integer employeeId) { Employee employee = null; try { employee = (Employee)super.getSession().get(Employee.class, employeeId); //Hibernate立即加载关联对象 Hibernate.initialize(employee.getDepartment()); } catch (Exception e) { e.printStackTrace(); } finally { super.closeSession(); } return employee; } }
/** * 业务DAO 继承自 BaseHibernateDAO * @author Administrator */ public class HrDAO extends BaseHibernateDAO { /** * 获取雇员信息集合 * @return */ public List<Employee> getEmployeeList() { List<Employee> list = null; try { Criteria c = super.getSession().createCriteria(Employee.class); //设置标准查询 setFetchMode 模式 立即加载集合内所有关联对象 c.setFetchMode("department", FetchMode.JOIN); list = c.list(); } catch (Exception e) { e.printStackTrace(); } finally { super.closeSession(); } return list; } }
Categories: 网页编程