链接查询
以班级和学生为例子:
班级对学生如果是延迟加载。
team.hbm.xml
<set name="students" cascade="all" inverse="true" lazy="true" batch-size="3">
<key column="teamID"></key>
<one-to-many class="com.vo.Student"></one-to-many>
</set>
代码:
Team team = null;
Student stu = null;
Query q = session.createQuery("from Team t join t.students");
List list = q.list();
Object obj[] = null;
for(int i=0;i<list.size();i++)
{
obj = (Object[])list.get(i);//取得集合中的第I个数组
team=(Team)obj[0];//team是数组中的第一个对象
stu = (Student)obj[1];//stu是数组中的第2个对象
System.out.println(stu.getName()+"属于:"+team.getName());
}
tran.commit();
session.close();
System.out.println(team.getStudents().size());
打印结果:
Hibernate: select team0_.ID as ID0_0_, students1_.ID as ID1_1_, team0_.Name as Name0_0_, students1_.Name as Name1_1_, students1_.TeamID as TeamID1_1_ from test.team team0_ inner join test.student students1_ on team0_.ID=students1_.teamID
zhangfan属于:一中
tanlian属于:十一中
tuping属于:四中
BOSS测试属于:湖南科技大学
新学期属于:湖南科技大学
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.vo.Team.students, no session or session was closed
原因是在SESSION关闭以后,由于班级对学生是延迟加载,所以当要得到学生集合,报出了异常。
将以上延迟加载改为立即加载就OK了。
或者更改HQL
Query q = session.createQuery("from Team t join fetch t.students");
运行程序发现报出类型转换异常。
更改代码:
Team team = null;
Student stu = null;
Query q = session.createQuery("from Team t join fetch t.students");
List list = q.list();
Object obj[] = null;
for(int i=0;i<list.size();i++)
{
/* obj = (Object[])list.get(i);
team=(Team)obj[0];
stu = (Student)obj[1];*/
team=(Team)list.get(i);
System.out.println(team.getName());
}
tran.commit();
session.close();
System.out.println(team.getStudents().size());
使用FETCH以后,类被初始化进入了TEAM的STUDENTj集合中。虽然TEAM对STUDENT是延迟加载,但是再HQL使用预先抓取以后,TEAM中的STUDENT集合被初始化了,所有在SESSION关闭以后还是可以打印STUDENT的信息。