//把fetch改成join就能解决couldnotinitializeproxy-theowningSessionwasclosed这个问题innerjoin(内连接)leftouterjoin(左外连接)rightouterjoin(右" />

解决hibernate中的lazy的问题

系统 1708 0
 <many-to-one name="TCustomerComeCategory" class="com.hnyxsm.modules.customer.TCustomerComeCategory" fetch="join">
//把fetch改成join就能解决 could not initialize proxy - the owning Session was closed这个问题
inner join (内连接)

left outer join (左外连接)

right outer join (右外连接)

full join (全连接,并不常用)

语句inner join , left outer join 以及 right outer join 可以简写。
from Cat as cat     join cat.mate as mate    left join cat.kittens as kitten

通过HQL的with关键字,你可以提供额外的 join 条件。
from Cat as cat     left join cat.kittens as kitten         with kitten.bodyWeight > 10.0

还有,一个" fetch "连接允许仅仅使用一个选择语句就将相关联的对象或一组值的集合随着他们的父对象的初始化而被初始化,这种方法在使用到集合的情况下尤其有用, 对于关联和集合来说,它有效的代替了映射文件中的外联接 与延迟声明(lazy declarations).
from Cat as cat     inner join fetch cat.mate    left join fetch cat.kittens

一个 fetch 连接通常不需要被指定别名, 因为相关联的对象不应当被用在 where 子句 (或其它任何子句)中。同时,相关联的对象 并不在查询的结果中直接返回,但可以通过他们的父对象来访问到他们。
from Cat as cat     inner join fetch cat.mate    left join fetch cat.kittens child    left join fetch child.kittens

假若使用iterate()来调用查询,请注意 fetch 构造是不能使用的(scroll() 可以使用)。 fetch 也不应该与setMaxResults() 或setFirstResult()共用,这是因为这些操作是基于结果集的,而在预先抓取集合类时可能包含重复的数据,也就是说无法预先知道精确的行数。 fetch 还不能与独立的 with条件一起使用。通过在一次查询中 fetch 多个集合,可以制造出笛卡尔积,因此请多加注意。对bag映射来说,同时 join fetch 多个集合角色可能在某些情况下给出并非预期的结果,也请小心。最后注意,使用full join fetch 与 right join fetch 是没有意义的。

如果你使用属性级别的延迟获取(lazy fetching)(这是通过重新编写字节码实现的),可以使用 fetch all properties 来强制Hibernate立即取得那些原本需要延迟加载的属性(在第一个查询中)。
from Document fetch all properties order by name
from Document doc fetch all properties where lower(doc.name) like ''%cats%''
通常情况下,我们并不使用映射文档进行抓取策略的定制。更多的是,保持其默认值,然后在特定的事务中, 使用HQL的左连接抓取(left join fetch ) 对其进行重载。这将通知 Hibernate在第一次查询中使用外部关联(outer join),直接得到其关联数据。 在条件查询 API中,应该调用 setFetchMode(FetchMode.JOIN)语句。
 在没有使用Spring提供的Open Session In View情况下,因需要在service(or Dao)层里把session关闭,所以lazy loading 为true的话,要在应用层内把关系集合都初始化,如 company.getEmployees(),否则Hibernate抛session already closed Exception;    Open Session In View提供了一种简便的方法,较好地解决了lazy loading问题.    
    它有两种配置方式OpenSessionInViewInterceptor和OpenSessionInViewFilter(具体参看SpringSide),功能相同,只是一个在web.xml配置,另一个在application.xml配置而已。    
     Open Session In View在request把session绑定到当前thread期间一直保持hibernate session在open状态,使session在request的整个期间都可以使用,如在View层里PO也可以lazy loading数据,如 ${ company.employees }。当View 层逻辑完成后,才会通过Filter的doFilter方法或Interceptor的postHandle方法自动关闭session。
     OpenSessionInViewInterceptor配置
Xml代码 复制代码
  1.      
  2. < beans >     
  3. < bean   name = "openSessionInViewInterceptor"   class = "org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor" >     
  4. < property   name = "sessionFactory" >     
  5. < ref   bean = "sessionFactory" />     
  6. </ property >     
  7. </ bean >     
  8. < bean   id = "urlMapping"   class = "org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >     
  9. < property   name = "interceptors" >     
  10. < list >     
  11. < ref   bean = "openSessionInViewInterceptor" />     
  12. </ list >     
  13. </ property >     
  14. < property   name = "mappings" >     
  15. ...    
  16. </ property >     
  17. </ bean >  ...  </ beans >    
        
<beans> 
<bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"> 
<property name="sessionFactory"> 
<ref bean="sessionFactory"/> 
</property> 
</bean> 
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
<property name="interceptors"> 
<list> 
<ref bean="openSessionInViewInterceptor"/> 
</list> 
</property> 
<property name="mappings"> 
... 
</property> 
</bean> ... </beans> 

    

OpenSessionInViewFilter配置
Xml代码 复制代码
  1.     
  2. < web-app >     
  3. ...    
  4. < filter >     
  5. < filter-name > hibernateFilter </ filter-name >     
  6. < filter-class >  org.springframework.orm.hibernate3.support.OpenSessionInViewFilter  </ filter-class >     
  7. <!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->     
  8. < init-param >     
  9. < param-name > singleSession </ param-name >     
  10. < param-value > true </ param-value >     
  11. </ init-param >     
  12. </ filter >  ...  < filter-mapping >     
  13. < filter-name > hibernateFilter </ filter-name >     
  14. < url-pattern > *.do </ url-pattern >     
  15. </ filter-mapping >  ...  </ web-app >    

解决hibernate中的lazy的问题


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论