转载:
HIBERNATE的持久化对象加载策略。
延迟加载, 也就是用到的时候才去加载.这样可以提高一些性能.
Hibernate的lazy loading 采用了一个HibernateSession来管理session,它的逻辑是每进行一次数据库操作,就开新的session,操作完成后立即关闭该session。这样做的好处是可以严格关闭session,避免菜鸟级的错误,但是hibernate.org并不推荐这么做。因为这不适合lazy loading,也不适合跨方法的事务。
比如在我们的应用中,user->post形成一对多的映射,User中有一个包含post的List。
在User中,有多个属性:name,password,phone等,还有一个List类型的posts。当我们对posts使用lazy laoding的时候,hibernate会在获得User对象的时候,仅仅返回name,password,phone等基本属性,当你访问posts的时候,它才会从数据库中提取posts需要的数据,这就是所谓lazy laoding。但是在我们的系统中,session是被立即关闭的,也就是在读取了name,password,phone等基本属性后,session已经close了,再进行lazy loaiding就会有异常。
解决办法是在close session之前,调用Hibernate.initialize(user.getPosts()),告诉系统,user.getPosts()是需要lazy laoding的。但是这样做会破坏HibernateSession类的封装.
后来采用所谓的OpenSessionInView模式,把session的周期交给servlet filter来管理,每当有request进来,就打开一个session,response结束之后再关闭它,这样可以让session存在于整个请求周期中。
本文主要针对一对多情况下读取父类的子集合时,hibernate 的lazy属性在其中的影响进行总结。(以下代码运行在jdk1.5,jboss eclipse ide 1.5,hibernate 3.1环境下) 假设有:父类 Person (含有Set类型属性Address), 子类 Address(碰巧集合的名字和子类的名字都是Address,不要混淆了) Person.hbm.xml 主要片段: <id name="idx" column="idx" type="long" > <generator class="identity"> </generator> </id> <property name="age" type="int" update="true" insert="true" column="age" /> <property name="name" type="java.lang.String" update="true" insert="true" column="name" /> <set name="address" table="address" lazy="true" cascade="none" sort="unsorted" > <key > <column name="personidx" /> </key> <one-to-many class="com.abc.common.pojo.Address" />
</set> (1)在session 的周期内,无论lazy 设为true or false, 不会有任何限制。访问父子数据的代码如下所示 : //打开session session = HibernateUtil.currentSession();
PersonDAO dao = new PersonDAO(); Person person = null;
person = (Person)dao.findByPrimaryKey(4); Set addressSet = person.getAddress();
Address[] addressAry = new Address[addressSet.size()]; Address address = null ; addressSet.toArray(addressAry);
for(int i=0 ;i<addressAry.length;i++){ ................ } //session关闭 session.close(); if (session.isOpen()){ HibernateUtil.closeSession(); }
(2)在session的周期外,访问父子数据的代码如下所示 : //打开session session = HibernateUtil.currentSession();
PersonDAO dao = new PersonDAO(); Person person = null;
person = (Person)dao.findByPrimaryKey(4); /********************** *留待后续处理 *********************/ session.close();
//session关闭之后才访问person的子集 Set addressSet = person.getAddress();
Address[] addressAry = new Address[addressSet.size()]; Address address = null ; addressSet.toArray(addressAry);
for(int i=0 ;i<addressAry.length;i++){ ................ } if (session.isOpen()){ HibernateUtil.closeSession(); }
此时,上述代码的运行结果根据lazy的设置的不同而不同 lazy=false 结果:可以访问得到Person和Address的数据 lazy= true 根据代码的写法有不同 (1)代码其他处不做任何处理,则抛出异常 org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: 。。。。。。 (2)如果做一些处理如下,将上述那段代码中的"留待后续处理"换成以下代码 Hibernate.initialize(person.getAddress()); 则可以访问得到Person和Address的数据 实际编写时,不会象上述这样的写法,即将 Hibernate.initialize(person.getAddress());和person.getAddress()在同一个方法里面调用。他们往往出现在应用程序的不同层次中(前者出现在DAO层居多,而后者则出现在web层居多).
|
分享到:
相关推荐
hibernate 中的lazy属性的使用
Hibernate 的 lazyload 在FLEX中的解决方法例子 用的是gilead 因为LIB包太大上传很慢所以被我删掉了。
Dwr+Hibernate的Lazy问题 解决了Hibernate延迟加载失效问题
博文链接:https://llying.iteye.com/blog/221699
Hibernate延时加载与lazy机制.docHibernate延时加载与lazy机制.doc
Hibernate fetch lazy cascade inverse 关键字
NULL 博文链接:https://xuwoool.iteye.com/blog/1306207
Hibernate中Cascade和inverse的区别,讲解的很详细
注意:在Hibernate3中,第二个要求并非是Hibernate强制必须的。但最好这样做。 你不能使用一个IdentifierGenerator产生组合关键字。一个应用程序必须分配它自己的标识符。 使用<composite-id> 标签(并且内嵌元素...
19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读缓存(Strategy: read only) 19.2.3. 策略:读/...
NULL 博文链接:https://quicker.iteye.com/blog/662613
博文链接:https://llying.iteye.com/blog/221700
19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读缓存(Strategy: read only) 19.2.3. 策略:读/...
19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读缓存(Strategy: read only) 19.2.3. 策略:读/...
NULL 博文链接:https://afuer.iteye.com/blog/1508008
Hibernate环境搭建 Hibernate主要接口 Hibernate主要映射 Hibernate的lazy、fetch、cascade等策略 Hibernate性能优化
19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读缓存(Strategy: read only) 19.2.3. 策略:读/...
019 关联映射文件中集合标签中的 lazy(懒加载)属性 020 、单端关联上的 lazy(懒加载)属性 021 继承关联映射 022 component(组件)关联映射 023 复合主键 关联映射 024 其它 关联映射 025 hibernate 悲观锁、乐观锁 ...
hibernate映射lazy策略hibernate查询语言hql
Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术。这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录。通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销。...