Hibernate延时加载与lazy机制

1.延迟加载(load)


      是Hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据时才会创建

      由于hibernate采用了lazy=true,这样当你用hibernate查询时,返回实际为利用cglib增强的代理类,但其并没有实际填 充;当你在前端,利用它来取值(getXXX)时,这时Hibernate才会到数据库执行查询,并填充对象,但此时如果和这个代理类相关的session已关闭掉,就会产生种错误。


       在做一对多时,有时会出现"could not initialize proxy - clothe owning Session was sed,这个是hibernate的缓存问题.问题解决:需要在< many-to-one>里设置lazy="false". 但有可能会引发另一个异常叫failed to lazily initialize a collection of role: XXXXXXXX, no session or session was closed?


解决方法:在web.xml中加入如下代码就可以了:

< filter> 
<filter-name>hibernateFilter</filter-name> 
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
< url-pattern>*.do</url-pattern>
</filter-mapping>




2.延迟加载的过程


      通过代理(Proxy)机制来实现延迟加载。Hibernate从数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据(除标识符外),Hibernate并不从数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都为默认值;只有在真正需要使用该对象的数据时才创建这个真正的对象,真正从数据库中加载它的数据。

     当调用Session上的load()方法加载一个实体时;当Session加载某个实体时,会对这个实体中的集合属性值采用延迟加载;当Session加载某个实体时,会对这个实体所单端关联的另一个实体对象采用延迟加载



Hibernate中默认采用延迟加载的情况主要有以下几种



• 当调用Session上的load()方法加载一个实体时会采用延迟加载。

• 当Session加载某个实体时,会对这个实体中的集合属性值采用延迟加载。(one-to-many)

• 当Session加载某个实体时,会对这个实体所单端关联(one-to-one, many-to-one)的另一个实体对象采用延迟加载。

• 第二种和第三种的区别是:第二种情况下取消延时加载的方法是在单方即有set属性的一方的映射文件的set标签后设置懒加载的属性lazy=“false”;第三种情况则是在多方即有many-to-one的一方的映射文件中的many-to-one标签后设置lazy=“false”。



    能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。



3. 抓取策略(fetch)


     通过配置“抓取策略”来直接影响session的get()和load()方法的查询效果。

     单端关联<many-to-one><one-to_one>上的抓取策略:

     可以给单端关联的映射元素添加fetch属性。select:延迟加载; join:在同一条select语句使用内连接来获得对象的数据和它关联对象的数据,此时关联对象的延迟加载失效。


    集合属性上的抓取策略:


     select:延迟加载;join:在同一条select语句使用内连接来获得对方的关联集合。此时关联集合上的lazy会失效。

     subselect:另外发送一条查询语句或子查询抓取。这个策略对HQL的查询也起作用。




评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值