`

org.hibernate.LazyInitializationException: failed to lazily initialize a collect

阅读更多
这个问题一般出现在一对多的情况下,解决的方法有两种
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>
分享到:
评论

相关推荐

    广东省深圳市文汇中学2015届九年级英语上学期第7周周末作业(答案不全) 牛津深圳版

    `lazily`:金鱼慵懒地(lazily)成群结队地在水面下游动。 - 15. `coats`:他们给前门刷了三层(coats)油漆。 2. **关键短语或词组**: - 1. `come along`:一起来,过来。 - 2. `a novel called…`:一本叫做...

    广东省广州市2018年中考英语学科模拟题十六20180709274

    3. 冠词:"a good worker",不定冠词a用于表示泛指,此处表示“一个好工人”。 4. 形容词与过去分词的区别:"Although surprised",形容词surprised用于表示人的感受。 5. 连词:"because he really needed help",...

    Packt.Mastering.Csharp.and.NET.Programming

    - **.NET as a Reaction to the Java World**: Microsoft’s response to Sun Microsystems’ Java platform, aiming to provide a robust framework for building and running applications. - **The Open Source...

    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....

    ksadaful.github.io:个人网站

    10. **性能优化**:使用`requestAnimationFrame`进行动画更新,或者利用`Lazily Load Images`等策略提高网站加载速度,都是JavaScript性能优化的常见手段。 11. **错误处理**:为了确保网站的健壮性,开发者可能...

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

    - 完成句子练习可以帮助巩固词汇的应用,如:"The young man rose lazily and was not willing to greet us."(年轻人懒洋洋地起身,并不愿意向我们打招呼。),"This appointment was greeted with relief."(这个...

    Free Hex Control

    / specific area difficult, so I lazily redraw almost the whole control whenever / it needs. This results in the slowness (I suggest you can use the control in data / display, ^_^). In next version,...

    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, ...

    Git-2.21.0-64-bit.zip

    committed, the command line prompt script failed to notice the current status, which has been improved. * Many GIT_TEST_* environment variables control various aspects of how our tests are run, ...

    Pandas Cookbook 2017 pdf 2分

    Slicing rows lazily Getting ready How to do it... How it works... There's more... Slicing lexicographically Getting ready How to do it... How it works... There's more... 5. Boolean Indexing ...

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

    - 以辅音字母+y结尾的词,如"lazily",改y为i再加"-er/est",形成"lazier"和"laziest"。 - 以不发音的e结尾的形容词,如"large",直接加"-r/-st",得到"larger"和"largest"。 - 多音节和某些双音节词,如...

    ModalDB:为进行多模态数据研究而优化的数据库。 为斯坦福人工智能实验室的 Robo Brain 项目构建

    例如: In [1]: video_frame['subtitles'] # loads quickly from in-memory...In [2]: video_frame['image'] # loads lazily from disk能够定义数据对象的任意嵌套层次结构。 例如,“视频”可以具有关联的属性...

    第 2-6 课:使⽤ Spring Boot 和 Thymeleaf 演示上传⽂件1

    spring.servlet.multipart.resolve-lazily=false ``` 在实际应用中,为了处理文件上传,我们需要创建一个Controller,它会接收前端发送的文件。`MultipartFile`是Spring提供的接口,用于处理文件上传请求。以下是一...

    新概念英语第二册单元测试答案.doc

    2. **情态动词**:A部分中的情态动词如can(能),must(必须),may(可能),might(可能),could(能够)等展示了不同可能性和必要性的表达。在E部分中,针对这些情态动词的否定形式进行了提问和回答,帮助学生...

    安卓 image

    包括选择合适的图片格式(如WebP)、压缩图片大小、利用惰性加载(Lazily load images)等技术。 综上所述,"安卓 image"涉及了Android开发中的图像资源管理、菜单设计、全屏模式的实现以及图像的显示和处理等多个...

    svc.rar_Will

    在这样的上下文中,"lazily created"可能意味着某些对象或服务会在实际需要时才进行实例化,以优化性能和资源利用率。 3. **svc.c**: "svc"通常代表"Service",这可能是实现某种特定服务的代码,如网络服务、系统...

    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-...

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

    npm install --save react-lazily-render 用法 () import React from 'react' ; import LazilyRender from 'react-lazily-render' ; ...lots of content... &lt; LazilyRender xss=removed&gt; } content = { ...

    2021届福建省高三英语三校联考试题答案.docx

    题目中给出的每篇文章后都有对应的答案,例如A篇21-23题答案为DDB,这表明学生需要通过阅读原文,理解文章内容,然后选择正确答案。 2. **七选五**:这种题型要求学生根据文章内容,从七个选项中选出五个最合适的...

    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 ...

Global site tag (gtag.js) - Google Analytics