随笔 - 6  文章 - 129  trackbacks - 0
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(14)

随笔档案(6)

文章分类(467)

文章档案(423)

相册

收藏夹(18)

JAVA

搜索

  •  

积分与排名

  • 积分 - 822216
  • 排名 - 49

最新评论

阅读排行榜

评论排行榜

假设有一个类A,它有两个属性property1和property2,则HQL语句"from A as a left outer join a.property1"有一个原则--HQL语句忽略配置文件的预先抓取策略,这句话有两个意思:

1.不管A类对property1在配置文件里是什么策略(可能是预先抓取,立即或延迟检索,它们都失效),这时都采用HQL指定的左外连接;左外连接必定会初始化property1属性(或对象),但是如果配置文件里对property1的检索策略是延迟加载,A类得 到对properyt1的引用,为了得到这个引用,需要再次发送一条SQL语句来确立这种引用关系,这种情况在property1为集合时经常出现.

2.A类在配置文件中设置的对property2的预先抓取策略将被忽略(不管这个策略是fetch或是select),对property2有影响的设置是立即和延迟加载,hibernate只看得到这两种策略,所以在使用语句"from A as a left outer join a.property1"时,property2的加载策略将仅由lazy="true"或者是lazy="false"来决定 


Team.hbm.xml 
...    ...
       <set name="students" inverse="true" cascade="all" lazy="true" fetch="join"><!-- 一对多的延迟加载设置 -->
            <key>
                <column name="TEAMID" length="32" not-null="true" />
            </key>
            <one-to-many class="edu.dgut.ke.model.Student" />
        </set>
...    ...
Student.hbm.xml
...    ...
        <many-to-one name="certificate"
         class="edu.dgut.ke.model.Certificate"
         unique="true"
         column="cardId"
         cascade="all"
         lazy="false"
         fetch="join">
        </many-to-one>
        <many-to-one name="team" class="edu.dgut.ke.model.Team" fetch="join">
            <column name="TEAMID" length="32" not-null="true" />
        </many-to-one>
...    ...
测试代码
  Session session = HibernateSessionFactory.getSession();
  List list = session.createQuery("from Student as s left join s.team").list();
  HibernateSessionFactory.closeSession();
  //list 包括两个长度为2的数组,每一个数组中包括一个学生对象和一个班级对象
  Object[] stuAndTeam1 = (Object[]) list.get(0);
  Student stu = (Student) stuAndTeam1[0];
  System.out.println(stu.getStudentname());
  System.out.println(stu.getTeam().getTeamname());
  System.out.println(stu.getTeam().getStudents().size());

控制台输出
Hibernate: select student0_.ID as ID0_0_, team1_.ID as ID2_1_, student0_.cardId as cardId0_0_, student0_.TEAMID as TEAMID0_0_, student0_.STUDENTNAME as STUDENTN4_0_0_, team1_.TEAMNAME as TEAMNAME2_1_ from STUDENT student0_ left outer join TEAM team1_ on student0_.TEAMID=team1_.ID
Hibernate: select certificat0_.ID as ID1_0_, certificat0_.`DESCRIBE` as DESCRIBE2_1_0_ from CERTIFICATE certificat0_ where certificat0_.ID=?
Hibernate: select certificat0_.ID as ID1_0_, certificat0_.`DESCRIBE` as DESCRIBE2_1_0_ from CERTIFICATE certificat0_ where certificat0_.ID=?
张三
05计算机应用技术(1)班
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: edu.dgut.ke.model.Team.students, no session or session was closed
 at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
 at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
 at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:97)
 at org.hibernate.collection.PersistentSet.size(PersistentSet.java:114)
 at edu.dgut.ke.test.chapter3.Query.main(Query.java:44)


注意:在配置文件中设置的检索策略只能影响到session.get()或者session.load()方法,对于直接使用
session.createQuery("from Student as s left join s.team")这种指明HQL的方式,将忽略配置文件的预先抓取检索策略(学生对班级的预先检索策略被忽略),这语句指明了学生和班级之间使用左外连接策略,因此控制台输出的第一条语句,即使用了左外连接得到了3个对象:2个学生和1个班级。
        得到了学生对象之后,学生以身份证的预先抓取策略失效,所以会有第二条和第三条语句,即使用了立即加载
        得到班级对象后,由于班级对学生采用延迟加载(这个策略不会被忽略),于是班级的学生集合并未得到初始化,所以当输出学生的人数,就抛出了例外。

posted on 2007-11-06 15:08 Ke 阅读(1198) 评论(0)  编辑  收藏 所属分类: hibernate

只有注册用户登录后才能发表评论。


网站导航: