`

hibernate 延迟加载的错误 failed to lazily initialize a collection of role

阅读更多
http://buptdavid.blog.51cto.com/745925/157509



这个问题一般出现在一对多的情况下,解决的方法有两种
1、设置lazy=false
如果是用annotation,则配置如下
@OneToMany(
   targetEntity = CourseAuthorizationItem.class,
   cascade = {CascadeType.PERSIST, CascadeType.MERGE},
   mappedBy = "course", fetch=FetchType.EAGER
  )
将fetch类型设置成直接获取

2、就是使用filter,过滤所有的链接
如果在使用filter的时候,要配置事务处理,否则会导致session处于只读状态而不能做修改、删除的动作

<web-app>

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</filter-class>
</filter>

<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>

</web-app>




failed to lazily initialize a collection of role: XXXXXX, no session or session was closed
例如:failed to lazily initialize a collection of role: com.gtc.wzgl.model.User.roles, no session or session was closed
这个异常大致意思是说在多对一的时候(并且lazy="false"),对象的实例失败,多数出现的情况有
1、粗心造成
实例对象类名写错之类的
2、逻辑错误
如之前就已经传递过来一个实体对象,然后调用实体对象的方法时牵涉到1对多的情况,但此时SESSION已经关闭,所以根本无法进行一对多的操作。
3、设计到跨度的问题:
这样打比方有多个实体对象,他们直接或则间接的有关联。比如有4个实体,分别是广告信息、广告、广告问答题、广告商:他们之间的关系为:
广告商 1:n 广告
广告 1:n 广告问答题
广告商 1:n 广告商信息
大家可以看到广告和广告商信息是没有直接关系的。但我要添加广告的时候我就必须将广告商的实体做为条件。那么这么一来广告商信息可能间接的就必须用上。下面看我的操作:
ad(广告),subject(题目)
     Ad ad = new Ad();
     ad.setAdProd(adform.getAdProd());
     ad.setIndustry(industry);
     ad.setAdPicture(pagefile.getFileName());
     ad.setAdFlack(adform.getAdFlack());
     ad.setAdDv(dvfile.getFileName());
     ad.setAdContent(adform.getAdContent());
     ad.setGray(gray);
     ad.setAdDate(new Date());
     ad.setOnlinetime(new Long(0));
     //以上为广告的基本信息填写,而重要的是看下面一句,在这里我的思路是subjectFormList是一个动态提交的表单,里面有若干个广告问答题。我将这些问答题变为一个Set,然后作为ad的一个属性。
     Set<Subject> subjectset=getSubjectSet(subjectFormList,ad);
     ad.setSubjects(subjectset);
//然后提交,makePersistent是一个封装的方法,用途就是save()啦。addao是一个DAO,里面有ADUS。
addao.makePersistent(ad);
表面上看来很符合逻辑,只要我们在ad的映射里面加上对subject的级联更新就可以完成这项操作。但实际上会发生我们意想不到的问题,来让我们看一下getSubjectSet()的内容:
public Set getSubjectSet(List<SubjectForm> subjectlist,Ad ad)
{
   Set<Subject> set=new HashSet<Subject>(0);
   Subject subject;
 
   for(Iterator<SubjectForm> it=subjectlist.iterator();it.hasNext();)
   {
    subject=new Subject();
    SubjectForm sf=it.next();
    subject.setSuContent(sf.getSucontent());
    subject.setSuOption(sf.getSuoption());
    subject.setSuResult(Arrays.deepToString(sf.getSuresult()));
    subject.setSuType(String.valueOf(sf.getSutype()));
    subject.setAd(ad);
    set.add(subject);
   }
 
 
   return set;
 
}
我们在这个方法上设一个断点然后跟踪,之后你会发现断点在set.add(subject)只后就会出failed to lazily initialize a collection of role: XXXXXXXX no session or session was closed这个异常,并且这个异常还是出在了广告商的广告信息上 gray.messages。是不是很不可理解?这也是Hibernate的懒汉机制问题。没有任何一样技术是完美的。那我们该怎么处理这样的问题。有很多人以为我们在广告商对广告商信息的隐射上加lazy="false"这样在对gray操作会对messages进行关联,并查询时提出数据。但你会发现改完之后会出现org.hibernate.LazyInitializationException: illegal access to loading collection这个异常。并切lazy="false"是我们不推荐的一种方法。他会降低你的查询效率。
对于这样的情况最好的解决办法就是不要偷懒,对一个实体进行操作的时候就该用那个实体的DAO,即应该有2句HQL。如下把getSubjectSet()改一改:
public void getSubjectSet(List<SubjectForm> subjectlist,Ad ad)
{
   Set<Subject> set=new HashSet<Subject>(0);
   SubjectDAO subjectdao=DAOFactory.getDao(SubjectDAO.class);
 
 
   for(Iterator<SubjectForm> it=subjectlist.iterator();it.hasNext();)
   {
    Subject subject=new Subject();
    SubjectForm sf=it.next();
    subject.setSuContent(sf.getSucontent());
    subject.setSuOption(sf.getSuoption());
    subject.setSuResult(Arrays.deepToString(sf.getSuresult()));
    subject.setSuType(String.valueOf(sf.getSutype()));
    subject.setAd(ad);
    subjectdao.makePersistent(subject);
    //set.add(subject);
   }
 
}//遍历出所有subject一个个的往数据库里加。这样便不会出问题了。
1、OpenSessionInView模式:
以下有2种方法,第1种是结合SPRING,第2种是采用了拦截器
Spring+Hibernate中,     集合映射如果使用lazy="true", 当PO传到View层时, 出现未初始化session已关闭的错误,只能在dao先初始化
parent.getChilds().size();

Spring提供Open Session In View来解决这个问题, 有两种方式
1. Interceptor
<!--</span><span style="COLOR: rgb(0,128,0)"> =========== OpenSession In View pattern ==============</span><span style="COLOR: rgb(0,128,0)">-->
    <bean id="openSessionInViewInterceptor"
             class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="interceptors" ref="openSessionInViewInterceptor"/>
        <property name="mappings">
            <props>
               ......
            </props>
        </property>
    </bean>
2. Filter
<web-app>

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</filter-class>
</filter>

<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>

</web-app>
第2种解决方法:
Hibernate.initialize()强制加载关联对象

今天又碰到错误
failed to lazily initialize a collection of role: no session or session was closed
试验了一下发现了几个解决方法:
1、是把对应一对多的那两个列lazy=true改为lazy=false即可
2、对于查询中如果用的是xxx.load(class,id)则改为xxx,get(class,id)
3在web.xml文件中加入
<filter>
   <filter-name>hibernateFilter</filter-name>
   <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
   <init-param>
            <param-name>singleSession</param-name>
            <param-value>false</param-value>
        </init-param>
<!--这个--   <init-param>一定要加不然很可能会报错:org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition
>
</filter>
<filter-mapping>
   <filter-name>hibernateFilter</filter-name>
   <url-pattern>*.mmg</url-pattern>
</filter-mapping>
本文出自 “千年一叹” 博客,转载请与作者联系!

分享到:
评论

相关推荐

    Qazy:延迟加载 - 没有 SEO 负面影响

    延迟加载 - 没有 SEO 负面影响 Qazy 是一个图像延迟加载器,并且与库无关(没有 jQuery)。 Qazy 消除了。 这就是它与其他惰性加载器的不同之处。 尽快在网页中加载脚本,以便它可以开始跟踪图像并延迟加载它们。 ...

    react-lazily-img:React Wrapper组件使用IntersectionObserver API延迟加载图像

    懒惰地ReactIMG React Lazily IMG是一个React Wrapper组件,用于延迟加载图像。 目标是使用方便且已知的标准HTML标记,并只是延迟加载它们。特征图片标签和IMG srcset支持Webp检测占位符HTML && CSS图像支持下载图像...

    Git-2.21.0-64-bit.zip

    * "git fetch" that grabs from a group of remotes learned to run the auto-gc only once at the very end. * A handful of Windows build patches have been upstreamed. * The code to read state files ...

    react-lazily-render:延迟安装昂贵的组件,直到将占位符组件滚动到视图中为止

    延迟安装昂贵的组件,直到占位符组件滚动到视图中为止。 安装 npm install --save react-lazily-render 用法 () import React from 'react' ; import LazilyRender from 'react-lazily-render' ; ...lots of ...

    Packt.Mastering.Csharp.and.NET.Programming

    - **A Quick Tip on the Execution and Memory Analysis of an Assembly in Visual Studio 2015**: Using tools like the Visual Studio Profiler to analyze the memory usage and performance of .NET ...

    springframework.5.0.12.RELEASE

    Exporting a lazily initialized bean (which implements SelfNaming and is annotated with ManagedResource annotation) gives IllegalStateException [SPR-17592] #22124 MockHttpServletRequest changes Accept-...

    JavaScript Concurrency pdf 无水印 0分

    Apply the core principles of concurrency to both browser and server side development Explore the latest tools and techniques at the forefront of concurrent programming, including JavaScript promises, ...

    Pandas Cookbook 2017 pdf 2分

    Table of Contents Preface What this book covers What you need for this book Running a Jupyter Notebook Who this book is for How to get the most out of this book Conventions Assumptions for every ...

    新特性源代码

    9. **延迟加载**:考虑到性能和用户体验,源代码可能会采用延迟加载技术,如Lazily加载图片或数据,只在实际需要时才加载,提高应用启动速度。 总的来说,这个“新特性源代码”提供了对ViewPager组件的深度定制,...

    Android代码-clojure-jsr223

    lazily. Copyright (c) 2009 Armando Blancas. All rights reserved. The use and distribution terms for this software are covered by the Eclipse Public License 1.0 ...

    Redis的Scala客户端Scredis.zip

    // Subscribes to a Pub/Sub channel using the internal, lazily initialized SubscriberClient redis.subscriber.subscribe("My Channel") {  case message @ PubSubMessage.Message(channel, ...

    2019_2020学年高中英语Unit4BodyLanguageperiod2WarmingUp&Reading2课件新人教版必

    例如,"After about ten minutes of waiting, I saw a middle-aged man enter her courtyard looking back carefully."中,"After about ten minutes of waiting"作为时间状语,描述动作发生的时间;"looking back ...

    get-all-files::high_voltage:具有懒惰同步和异步迭代器支持的快速递归目录搜寻器

    具有延迟同步和异步迭代器支持的出色的快速递归目录搜寻器。 安装 支持Node.js版本10及更高版本。 $ npm i get-all-files 用法 import getAllFiles from 'get-all-files' // Get array of filenames ...

    Free Hex Control

    / Errrrr...Actually, I hesitate to release the source code of this control, / Because when I checked after completion, I found that it's really ugly! Putting all / graphic codes in the CDraw class ...

    Android代码-ixjava

    The aim is to provide, lazily evaluated, pull-based datastream support with the same naming as in RxJava mainly for the pre-Java-8 world. The Stream API in Java 8 is not exactly the same thing because...

    前端面试-v21

    - ` Lazily loaded images`:利用`loading="lazy"`属性延迟加载图片。 开放式问题涉及的技能和流程,如JavaScript延迟加载技术、关注的技术趋势、开发流程与使用的工具、网站性能优化策略、原型继承和闭包的理解等...

    实现任意多个视图内容的滚动视图

    源码实现了怎样支持延迟加载(lazily load),可以任意多个视图内容的ScrollView。所谓延迟加载,即只加载需要显示的页面内容,即按需加载,从而当需要加载许多视图内容时,不会消耗过多内存。也支持循环滚动视图。...

    新概念英语第一册第109-110课PPT课件.pptx

    - "advice"意为"建议",常搭配"a piece of advice",动词形式如"give advice", "act on sb's advice"等。 4. 替代和程度副词: - "instead"表示"代替",如"There isn't any cigarette, have a biscuit instead....

    Android代码-Kodein-DI

    Kodein is a very simple and yet very useful dependency retrieval container. it is very easy to use and configure. Kodein works: On the JVM. On Android. On Javascript (both in the browser and on Node....

    Lazy ScrollView(iPhone源代码)

     支持延迟加载(lazily load) 任意多个视图内容的ScrollView。所谓延迟加载,即只加载需要显示的页面内容,即按需加载,从而当需要加载许多视图内容时,不会消耗过多内存。也支持循环滚动视图。 Code4App编译测试...

Global site tag (gtag.js) - Google Analytics