`
shift8
  • 浏览: 150002 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

11、hibernate下著名的延迟加载问题和1:N问题

阅读更多

问题描述:
如果延迟的操作是发生在CRUD的操作所在的session关闭之后,就会出现这个异常.

什么是延迟的操作?

1.fetch = "LAZY" 机制
ManyToOne,OneToMany,ManyToMany中对关联对象的延迟调用
读出持久化对象时,并不把关联的对象实际读出,而是延迟到访问到持久化对象的关联对象属性时,才向数据库发成读操作
2.load()方法
获取持久化对象的load()方法,并不把对象实际读出,而是延迟到 访问到持久化对象时,才向数据库发成读操作



load() 与 fetch=LAZY 机制有什么不同?
1.首先,二者很象,都是延迟调用,都会报LazyInitializationExcept2. load()是比fetch=LAZY 更lazy     因为fetch=LAZY是延迟调用关联对象入内存缓存
     load()是延迟整个 持久化对象,等于什么都没读入内存缓存


实验场景下的LazyInitializationException:no session or session was closed

       Session session1 = sf.getCurrentSession();
       Transaction tran1 = session1.beginTransaction();
           Group_3 group = (Group_3) session1.get(Group_3.class, 6);
           tran1.commit();          // 问题出在此语句,LAZY 前后两次发sql字串,跨了session
           for(User_3 user:group.getUsers() )
               System.out.println(user.getId()+":"+user.getName());
22:48:23,187 ERROR LazyInitializationException:42 - failed to lazily initialize a collection of role: com.machome.one2many_many2one_bi.Group_3.users, no session or session was closed



实际应用中的LazyInitializationException:no session or session was closed

servlet或action类:
List<xxx> xxxs = findAll();          // 此方法结束时,session就关闭了
request.setAttribute("xxxs",xxxs);

JSP页面:
显示request.getAttribute("xxxs");
22:48:23,187 ERROR LazyInitializationException:42 - failed to lazily initialize a collection of role: com.machome.one2many_many2one_bi.Group_3.users, no session or session was closed



延迟加载异常的解决
1.简单的解决办法---关闭LAZY机制

@ManyToOne(fetch=FetchType.EAGER)         
       hibernate多对一,Many端缺省就是EAGER机制,One端缺省是LAZY
优点:
简单,实现容易

缺陷:
1.fetch是ManyToOne,OneToMany,ManyToMany的机制,所以关闭它只能解决ManyToOne等的延迟加载异常,但无法解决load()方法的延迟加载异常

2.因为这等于是关闭延迟加载,所以无法享受延迟加载带来的对性能方面的益处

3.对ManyToOne,OneToMany双向的情况,两边都设FETCH=EAGER,有可能出现死锁的情况

2.更合理的解决办法---用spring的OpenSessionInViewFilter把session的周期交给servlet filter来管理
每当有request进来,就打开一个session,response结束之后才关闭它,这样可以让session存在于整个servlet request请求周期中

采用spring的OpenSessionInView模式

web.xml下加入:
<!-- ##################### 解决Lazy Initial Exception问题 ###########-->
    <filter>
            <filter-name>OpenSessionInViewFilter</filter-name>
            <filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

            </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>OpenSessionInViewFilter</filter-name>
         <url-pattern>*.do</url-pattern>
    </filter-mapping>
   
    <filter-mapping>
        <filter-name>OpenSessionInViewFilter</filter-name>
         <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
优点:
1.既能解决多对一得FETCH=LAZY问题,也能解决load()方法的问题
2.同时能允许用户使用FETCH=LAZY机制和load()方法,享受其带来的对性能的提升 .

缺陷:
1.需要整合hibernate入spring
2.仅支持java web环境,对java application 环境不支持


                  
和hibernate一样秉承OrMapping Persistence理论的JPA下也有延迟加载异常
下面是spring 针对JPA的servlet过滤器

web.xml下加入:
<filter>
   <filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
   <filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>                                        
</filter>
<filter-mapping>
   <filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
   <url-pattern>*.action</url-pattern>
</filter-mapping>



所谓的1+N问题-----其实就是多对一一对多fetch=EAGER机制带来的对性能的损耗
每次获取持久化对象,都会同时调入关联对象,hibernate会发出多条select语句,很耗资源
解决方法:
1。fetch=LAZY   最常用
2. BatchSize
设@BatchSize,这样hibernate自动把N条组成一条或几条

分享到:
评论

相关推荐

    Hibernate面试题专栏 - 最全的Hibernate面试题, Hibernate笔试题, Hibernate问题

    以上只是Hibernate众多知识点的一部分,实际面试中可能涉及更多细节,如级联操作、事务隔离级别、延迟加载机制、乐观锁和悲观锁的区别等。熟悉并理解这些内容对于通过Hibernate相关的面试至关重要。

    hibernate-orm-master.zip

    为了提升性能,Hibernate提供了多种优化手段,如:批处理(Batch Processing)、预加载(Preloading)、缓存策略调整、避免N+1查询问题等。理解并运用这些技巧,可以在保证代码简洁的同时,提升应用性能。 通过深入...

    hibernate-release-4.2.8.Final.zip

    2. **延迟加载优化**:延迟加载是Hibernate的一个重要特性,4.2.8.Final 在这方面进行了优化,避免了不必要的数据加载,减少了内存消耗。 3. **事务管理**:该版本增强了对Spring事务管理的支持,使得在Spring环境...

    最新hibernate 4.1.1.Final版本

    9. **延迟加载(Lazy Loading)**:Hibernate支持延迟加载,即只有在真正需要访问某个关联对象时,才会去数据库加载,有效避免了“N+1”查询问题。 10. **多态性支持**:Hibernate支持多态查询,使得继承体系中的...

    hibernate源码release-4.1.4.Final版

    包括但不限于:合理使用缓存,避免N+1查询问题,使用批处理更新,选择合适的主键生成策略,以及优化HQL和SQL查询等。 通过深入学习Hibernate 4.1.4.Final的源码,我们可以更好地理解其设计思想,提升我们的编程技巧...

    hibernate-release-5.2.10

    3. 精细控制查询:避免N+1查询问题,合理使用JOIN,避免过多的子查询。 总结,Hibernate 5.2.10提供了一套完整的持久化解决方案,简化了Java应用程序与数据库的交互。通过理解和掌握其核心概念、API用法及最佳实践...

    hibernate-3.4.0

    4. **查询优化**:避免N+1查询问题,优化HQL或SQL,减少结果集大小。 八、其他特性 1. **Callback事件**:如PrePersist、PostUpdate等,允许在特定操作前后执行自定义逻辑。 2. **实体状态管理**:Hibernate管理...

    hibernate源码文件

    1. 分批加载(Lazy Loading):延迟加载策略,只在真正需要时加载关联对象。 2. 批量操作:使用批处理提高数据库操作效率。 3. 预加载(Eager Loading):避免N+1查询问题,一次性加载所有关联对象。 4. 第二级别...

    hibernate 4.2.4精简jar包

    - **懒加载和级联操作**: 支持延迟加载,只在需要时加载关联对象,减少内存占用;级联操作使得对一个对象的操作能影响到与其关联的对象。 - **查询语言**: Hibernate查询语言(HQL)和Criteria API,提供强大的...

    hibernate-3.6.8.Final

    包括批处理(Batch Processing)、缓存策略调整、延迟加载(Lazy Loading)的合理使用、避免N+1查询问题等,都是提升Hibernate性能的关键。 总结,Hibernate 3.6.8.Final是开发者进行数据库操作的强大工具,通过...

    hibernate源码

    - **代理模式**:Hibernate使用动态代理来实现延迟加载和级联操作。 - **策略模式**:例如,缓存策略、事件监听策略等,都体现了策略模式的应用。 3. **工作流程** - **初始化**:通过配置文件或Annotation,...

    hibernate-distribution-3.3.2.GA版本的开发手册

    手册还涵盖了如何有效使用Hibernate的最佳实践,如避免N+1查询问题,正确处理大数据量操作等。 综上所述,`hibernate-distribution-3.3.2.GA`开发手册详尽地阐述了Hibernate的核心功能和使用技巧,对于Java开发者来...

    补充知识点实例(NHibernate)实例

    2.延迟加载(Lazy Loading):只在需要时加载关联对象,避免不必要的数据检索。 3. 查询优化:合理使用HQL或Criteria API,避免N+1查询问题。 七、实战应用 在实际项目中,NHibernate可以应用于Web应用、桌面应用等...

Global site tag (gtag.js) - Google Analytics