Hibernate懒加载常见问题及解决方案

来源:互联网 发布:深度睡眠知乎 编辑:程序博客网 时间:2024/06/06 02:24

什么是懒加载?

懒加载(Load On Demand)是一种独特而又强大的数据获取方法,它能够在用户滚动页面的时候自动获取更多的数据,而新得到的数据不会影响原有数据的显示,同时最大程度上减少服务器端的资源耗用。(百度说的)

通俗点,就是在找一个对象时不找出与他关联的对象,而是在需要相关联对象(或其属性)时才去数据库中找,也称之为延迟加载。


我们一般通过MyEclipse的逆向工程生成实体类,并为该类自动配置注解,该实体类有一个一对多的属性,这时hibernate自身提供给我们fetch = FetchType.LAZY这个属性:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "standard")public Set<Courier> getCouriers() {    return this.couriers;}

从代码上可以看到,该注解默认设置了延迟加载fetch = FetchType.LAZY。所以当应用程序查询该实体类对应的表的数据时,出现了以下错误:

org.hibernate.LazyInitializationException:could not initialize proxy - no Session
。。。。。省略。。。。。。

这意味着在读取数据的时候,Session已经关闭。
解决方案一:把FetchType.LAZY设置为EAGER,取消延迟加载机制。(不推荐)

fetch = FetchType.EAGER

解决方案二:在web.xml中添加一个过滤器,这个过滤器必须要位于Struts的核心过滤器之前
(推荐)

< filter>       < filter-name>hibernateFilter< /filter-name>       < filter-class>        org.springframework.orm.hibernate3.support.OpenSessionInViewFilter       < /filter-class>   < /filter>   < filter-mapping>       < filter-name>hibernateFilter< /filter-name>       < url-pattern>/*< /url-pattern>   < /filter-mapping> 

当然了,如果我们用了Spring整合Hibernate JPA,那么Session就被EntityManager所替换,这时我们推荐使用Spring框架提供过滤器:OpenEntityManagerInViewFilter
该过滤器作用的是,在访问视图层(包括Action层)之前开启session,在访问结束之后,关闭session

<!-- 必须放在struts2的过滤器之前 --><filter>    <filter-name>OpenEntityManagerInViewFilter</filter-name>    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class></filter><filter-mapping>    <filter-name>OpenEntityManagerInViewFilter</filter-name>    <url-pattern>/*</url-pattern></filter-mapping>
原创粉丝点击