首先请看清楚,不要没看清楚就回答!将 <set name="empAnnualVactions" inverse="true" lazy="true" 会报下面的错误org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role ********* no session or session was closed我不想问怎么解决,网上太多太滥的方法了,无非是将 lazy 设为 false。但是我就是想集合属性延迟加载呀。其实在 set里 加上 fetch = "join",也可以解决。 我想问的是, 出现 这种问题的根本原因是什么,是将 fetch ="select" 的原因吗?我看了下 fetch ="select" 的意思是说,他会先将 主表全部查询出来,然后在用 主表 关联字段 去取关联类。和 fetch ="join" 一句关联查询,只是效率上的差别吧。

解决方案 »

  1.   

    SESSION 开启
    事务开启
    获得实例对象---如果你将该对象放置到SESSION --这个是WEB SESSION,那么这个对象关联的集合有可能是没有初始化,因为配置了延迟加载。但是在这个小区域内关联对象是可以获得的。因为这要执行两次查询。
    事务关闭
    SESSION关闭当SESSION关闭后,你用获得的实例是不能在获得关联对象的。所谓的延迟加载是在当前连接中需要使用才进行查询。像页面使用关联对象是使用了OSIV-模式。连接关闭基本是在页面解析完成以后。
      

  2.   

    楼上的没有回答我的问题,为什么我将 fetch配置成 fetch = "join"就不会报错。照楼上的说。这样配了,session 就 开启了?其次,我没有将 对象放置到SESSION --这个是WEB SESSION。
      

  3.   

    例如,对于parent.getChildren()这样一个方法来说,parent对象是一开始就通过Hibenate对象拿到的,但是由于<one-to-many>的lazy属性设置为false,在get parent这个对象时候,并没有拿到其children。当真正用到children的时候,此时的parent已经变成托管状态的了,在托管态的对象是无法再次使用级联操作的。
    所以另外一种解决就是重新关联parent到session,然后执行一下getChildren(),当parent再次变成托管状态时,就不会出错了。
     
    重新获得一个session,然后利用session.update(parent),将其重新关联,变成持久态。在执行一下parent.getChildren()。
    这里需要注意另外一个问题,update时,会不会出现级联更新?
      

  4.   


    可我看见过别人配的程序,没有这么麻烦,也没有将 fetch 设为 'join',就是和我报错时一样配的,程序里面也没有什么和sessoin再关联一次这样的,可是人家的不会报错,人家现在不在公司了。
      

  5.   

    因为你fetch的时候是一次sql查询--将集合对象就初始化了!
    lazy是两次或是更多。
      

  6.   

    是,fetch设置为 join是会将 关联对象一起取出来,那不设置为 join,session取完 主档,就会自动关闭吗?
      

  7.   

    你看我第一次回复的最后一句话。你如果理解,那么别人配置那么简单就很容易理解了。request->session open--->逻辑操作--->session close--->response
      

  8.   

    呵呵!你session都关闭了还加载什么啊??
    你要写个过滤器之类的东西让你的session继续处于开启状态
      

  9.   

    要使用open session in view吧,spring实现了这个filter
      

  10.   

    忽略 8,9楼的回答,没有认真看。to: APOLLO_TSrequest->session open--->逻辑操作--->session close--->response  这个步骤。你的意思是说 做完一次读取操作,session会自动关闭??????
      

  11.   

    这个问题主要是SESSION关闭了,其实我觉得 延迟并不怎样.似乎没有什么用处,
    在关联时配置一对多,多对一.你取得一个不马上取它相关的集合或一个对象.通常是设TRUE.
    那怎么解决你的问题呢?
    比如:parent,children
    你取得了一个parent,lazy=true,这时不马上取children
    但你去要在页面上显示children,你觉得可以么?当然不行了,肯定是要再查询一次才有东西,但这时是延迟的,你想要它自动查,所以出错了.
    那如果不是自动查呢?比如我一个操作,需要同时取得parent和它的children,那就可以强制初始化这个children
    好像是initialize(parent.getChildren()),这样,配置文件还是延迟的,只对你这个操作可以加载它的children.
    而其它的操作还是延迟的.
    查出children然后要它的parent也是这样的,通常树结构就有这个,当然你可以设为false就不是延迟加载了.
      

  12.   

    用 Hibernate.initialize方法可以。但是想在配置里面就搞定。
      

  13.   

    以前也遇到过。
    一开始怎么都不理解。
    我没有像楼主那样的配置。
    我是在页面以开始就加载一个下拉框。
    是自己中间的逻辑出了问题,导致session会话提前关闭掉了。
    如果不是自己逻辑上的问题。那么可以在web。xml中配置  
    <!-- 延迟会话到view界面后在关闭-->
    <filter>
    <filter-name>openSession</filter-name>
    <filter-class>
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
    </filter>
    <filter-mapping>
    <filter-name>openSession</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>其次的解决方法也是最不推荐的解决方法就是在hbm文件中lazy=fase
    已般不到万不得已不建议在这里做更改。
    具体当时我的逻辑哪里问题我也忘了。一年前学习中遇到的了。所以给不了楼主好的解释了。抱歉。总共三种解决方法:1,检查逻辑。2:web.xml  3:hbm lazy=fase
      

  14.   

    不可能,fetch是抓取策略,和这个无关,
      

  15.   


    这个就是表示SESSION单独业务处理,业务处理后不直接关闭.
      

  16.   

    web.xml<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> 
     </filter><filter-mapping>
      <filter-name>hibernateFilter</filter-name>
      <url-pattern>/*</url-pattern>
     </filter-mapping>
      

  17.   

    如果回答两次是一种错,那回答三次可以算不可原谅了.
    延迟加载,在配置文件里就可以配置的.但你要加载东西就必须要有SESSION,所以你说的是不可能的.
    可能你看到你你以前的同事的代码有些没有看清楚(猜想)....
    如果你是砖家,随便扔.我想成为砖家 
      

  18.   


    我不用砖头拍你,我是来商量的,嘿嘿,言归真传吧,我取数据的时候,session没有关闭。
      

  19.   

    仅仅设置lazy=“true”,延迟加载等于没有加载;加上fetch=“join”:Hibernate通过 在SELECT语句使用OUTER JOIN(外连接)来获得对象的关联实例或者关联集合,加上和lazy=“false”一样;查询抓取(Select fetching) fetch=“select”,另外发送一条 SELECT 语句抓取当前对象的关联实体或集合.除非你显式的指定lazy="false"禁止延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条select语句;