常言笑的家

Spring, Hibernate, Struts, Ajax, RoR

Hibernate的延迟加载问题

        众所周知,到了Hibernate3.0以后,关联关系的对象默认都是使用延迟加载,例如<one-to-many>时.但我在映射<one-to-one>,<many-to-one>关系时指定了lazy="true",但是在查询对象时,我只想查询一个对象,仍然会把这个对象所关联的<one-to-one>,<many-to-one>对象一起查询出来,这样造成了极大的性能浪费.在不指定lazy属性时,<many-to-one>所关联的对象反而会延迟加载,这让我大为困惑,还以为是Hibernate的bug. 

        在网上查找资料,说在为了延迟加载<one-to-one>,<many-to-one>所关联的对象,需要设置被关联的对象<class name="" lazy="true">,我也这样做了,但是仍然没有效果.

         仔细阅读了Hibernate的手册,才发现原来要延迟加载<one-to-one>,<many-to-one>所关联的对象时,除了要指定lazy="true"外,还需要运行期字节码增强,而我省去了这一步,所以延迟加载没有效果.同时还发现在默认情况下,<one-to-one>,<many-to-one>的lazy属性是"proxy"而不是"true"!因此如果直接采用lazy的默认值,是可以延迟加载的.

总结一下:
        <many-to-one>默认的属性是lazy="proxy",此时默认是会延迟加载的.在指定了lazy="true"之后,必须要经过运行期字节码增加,延迟加载才有效果.
 
        而<one-to-one>相对要复杂一点,延迟加载还要受到constrained属性的限制.constrained="false"时表明实体和被关联到的实体的约束不是强制的,即存在一个实体时,它通过<one-to-one>关联的实体可能存在,也可能不存在,这时在查询实体时,Hibernate总会发起一次查询检查<one-to-one>所关联的实体是否存在,而这时已经可以把one-to-one关联的实体查询出来了,因此在<one-to-one>关系中,如果constrained="false",总是会立即加载关联到的实体.

        如果当constrained="true",且lazy="proxy"(默认),是可以延迟加载的.
        如果当constrained="true",且lazy="true"时,需要经过运行期字节码增加,延迟加载才会奏效.
 
Open Session In View
       使用Open Session In View就有一个好处,就是当页面需要使用关联后的实体时才会去查找缓存中是否已经有所需要的对象实体了,如果有直接返回结果,如果没有才重新查询。
 
cache
        cache就是Hibernate使用的缓存。如果你的数据是频繁更新的,比如银行系统,那么,你的数据做cache是不安全的,那么你的取数据的策略需要级别高一些,甚至是需要事务级的取缓存数据;如果你的数据是频繁读取,修改少的,我可以放心的缓存,不必设置过高的缓存并发控制级别,比如是论坛系统,那么你说的问题几乎不可能出现啊。
         两面性是有,但是我们根据场合,在合适的场合使用合适的一面,那就不ok了?我得问题讨论的前提是使用cache没有并发更新之类问题的前提下的,是指在使用cache时不需要考虑另一面性的前提下,这种情况下谈何两面性。
 
什么样的数据适合存放到第二级缓存中?
       1、很少被修改的数据
   2、不是很重要的数据,允许出现偶尔并发的数据
   3、不会被并发访问的数据
   4、参考数据

不适合存放到第二级缓存的数据?
   1、经常被修改的数据
   2、财务数据,绝对不允许出现并发
   3、与其他应用共享的数据。

posted on 2006-12-16 22:36 常言笑 阅读(300) 评论(0)  编辑  收藏 所属分类: 数据库


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


网站导航:
 

My Links

Blog Stats

常用链接

留言簿(5)

随笔分类

随笔档案

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜