`

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

 
阅读更多
问题描述:
如果延迟的操作是发生在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中的延迟加载技术进行深入剖析,帮助读者更好地理解和运用这项技术。 #### 二、基本概念 ##### 2.1 什么是延迟加载? 延迟加载是指在访问关联数据或集合数据时,只有在真正需要使用这些数据时才...

    Hibernate延迟加载案例 (多: 一: 一,附代码)

    本案例主要探讨的是Hibernate的延迟加载(Lazy Loading)机制,这是一种优化数据库访问性能的重要策略。延迟加载允许我们在需要数据时才去加载,而不是在初始化对象时一次性加载所有关联数据,从而减少了内存消耗和...

    hibernate延迟加载解决

    Hibernate 是一款流行的 Java 持久层框架,它支持多种加载策略,包括即时加载和延迟加载。在本文中,我们将重点讨论后者。 ##### 1. 实体对象的延迟加载 **配置方式:** 要在Hibernate中启用实体对象的延迟加载,...

    Hibernate 延迟加载剖析与代理模式应用

    《Hibernate延迟加载与代理模式解析》 在Java的持久化框架Hibernate中,延迟加载(Lazy Load)是一项重要的优化策略,其核心目标是提高系统性能,减少内存占用,避免不必要的数据库交互。延迟加载允许我们在需要...

    Hibernate延迟加载以及利用Spring

    ### Hibernate延迟加载以及利用Spring #### 一、Hibernate延迟加载概念与原理 ...综上所述,通过合理的配置和编码实践,可以在Spring框架下有效地使用Hibernate的延迟加载功能,从而优化应用性能并减少内存消耗。

    什么是hibernate延迟加载

    详细介绍hibernate延迟加载,对hibernate初学者有一定的帮助

    Flex 与 Hibernate 的延迟加载问题

    在开发Flex与Hibernate集成的应用时,延迟加载(Lazy Loading)是一个常见的挑战,因为Flex客户端无法直接理解和处理Hibernate的延迟加载机制。延迟加载是一种优化策略,它允许关联的对象在真正需要时才被加载,而...

    Hibernate集合属性的延迟加载.doc

    在 Hibernate 框架中,延迟加载(Lazy Loading)是一种优化数据访问性能的重要技术。它允许我们只在真正需要数据时才从数据库加载,避免一次性加载大量数据导致的内存消耗和性能瓶颈。当我们处理与实体相关的集合...

    Hibernate的延迟加载

    ### Hibernate的延迟加载详解 #### 实体对象的延迟加载 延迟加载是Hibernate中一项关键...然而,开发者需要注意正确地配置和使用延迟加载,以充分利用这一机制带来的优势,同时避免可能产生的陷阱,如N+1查询问题等。

    Hibernate延迟加载

    【延迟加载】是Hibernate框架中的一个重要机制,旨在优化性能,避免在不需要数据时就提前加载大量数据,从而减少不必要的...然而,过度依赖延迟加载可能会导致N+1查询问题,因此在设计和使用时需要权衡利弊,合理运用。

    Hibernate lazy延迟加载

    1. **N+1查询问题**:如果在循环中访问懒加载的关联属性,会导致大量额外的数据库查询,称为N+1查询问题。可以使用`JOIN FETCH`或子查询来预先加载关联数据,避免这种情况。 2. **初始化时机**:懒加载只能在session...

    浅析Java的Hibernate框架中的缓存和延迟加载机制

    主要介绍了Java的Hibernate框架中的缓存和延迟加载机制,Hibernate是注明的Java下SSH三大web开发框架之一,需要的朋友可以参考下

    hibernate 延迟加载.docx

    【hibernate 延迟加载】 在Java的持久化框架Hibernate中,延迟加载(Lazy Loading)是一种优化数据库访问性能的技术。它允许我们在需要时才加载关联的对象,而不是在初始查询时就一次性加载所有数据。这有助于减少...

    hibernate N+1问题解决办法

    在Java开发中,使用Hibernate作为ORM框架时,我们可能会遇到一个性能上的问题,那就是著名的“N+1查询问题”。此问题源于不恰当的数据加载策略,可能导致数据库查询效率低下,尤其在大数据量的情况下,会严重影响...

    Hibernate延迟加载介绍.doc

    《Hibernate延迟加载详解》 Hibernate作为Java领域中的一个强大的对象关系映射框架,提供了许多优化...然而,需要注意的是,过度依赖延迟加载可能会导致N+1查询问题,因此在设计时应综合考虑查询效率和代码的可读性。

    hibernate延迟加载技术详细解

    通常,在多对多或者一对多的关系中,延迟加载能够避免 N+1 查询问题。本文将详细探讨 Hibernate 的各种延迟加载策略及其应用场景。 #### 二、Fetching 策略 Fetching 策略定义了 Hibernate 在执行查询时如何获取...

Global site tag (gtag.js) - Google Analytics