1. 程式人生 > >關於Hibernate懶加載問題的最終解決方案

關於Hibernate懶加載問題的最終解決方案

ransac err work eth 功能 就會 過濾器 except 沒有

看到一篇Hibernate懶加載的文章,所以轉載,原地址如下:

http://tuoxie007.iteye.com/blog/334853

Hibernate的強大之處之一是懶加載功能,可以有效的降低數據庫訪問次數和內存使用量。但用的不好就會出現org.hibernate.LazyInitializationException。

這個異常出現的原因很簡單,主要時在加載懶數據時Session已經關閉造成的.

那麽OK,我們來考慮怎麽解決吧。

我們只要在渲染JSP之前不要關閉Session,而在JSP渲染之後再關閉就OK啊。我們知道,在JSP/Servlet中,可以配置過濾器來實現這種功能。

我們考慮兩種情況的解決方案:

單使用Hibernate和用Spring來管理Hibernate。

1. 單使用Hibernate:

我們可以自己寫一個過濾器:

import java.io.IOException;  
  
import javax.servlet.Filter;  
import javax.servlet.FilterChain;  
import javax.servlet.FilterConfig;  
import javax.servlet.ServletException;  
import javax.servlet.ServletRequest;  
import javax.servlet.ServletResponse;  
  
import org.hibernate.SessionFactory; import org.hibernate.StaleObjectStateException; import org.sunxin.struts2.util.hibernate.HibernateUtil; public class HibernateThreadFilter implements Filter { private SessionFactory sf=null; public void init(FilterConfig arg0) throws
ServletException { sf=HibernateUtil.getSessionFactory(); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { sf.getCurrentSession().beginTransaction(); chain.doFilter(request, response); sf.getCurrentSession().getTransaction().commit(); } catch (StaleObjectStateException staleEx) { throw staleEx; } catch (Throwable ex) { ex.printStackTrace(); try { //如果發生異常,讓事務回滾。 if (sf.getCurrentSession().getTransaction().isActive()) { sf.getCurrentSession().getTransaction().rollback(); } } catch (Throwable rbEx) { System.err.println(rbEx.toString()); } } } public void destroy(){} }

在web.xml中加入這個Filter的配置:

<filter>  
    <filter-name>HibernateThreadFilter</filter-name>  
    <filter-class>org.sunxin.struts2.filter.HibernateThreadFilter</filter-class>  
</filter>  
<filter-mapping>  
    <filter-name>HibernateThreadFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>  

這樣就在訪問後臺代碼之前打開session,訪問後臺代碼之後關閉session。

2. 用Spring管理Hibernate:

I . Spring為我們提供了這樣一個過濾器,我們這樣配置一下就OK。

在web.xml中加入Filter的配置:

<filter>  
    <description>處理Hibernate的懶加載問題</description>  
    <filter-name>openSessionInViewFilter</filter-name>  
    <filter-class>  
        org.springframework.orm.hibernate3.support.OpenSessionInViewFilter  
    </filter-class>  
    <init-param>  
        <description>  
            默認情況下,這個Filter會在Spring的bean池中找一個叫做sessionFactory的bean。如果使用了其他名字的SessionFactory,則應該在這裏  
            指定這個名字。  
        </description>  
        <param-name>sessionFactoryBeanName</param-name>  
        <param-value>sessionFactory</param-value>  
    </init-param>  
    <init-param>  
        <description></description>  
        <param-name>singleSession</param-name>  
        <param-value>true</param-value>  
    </init-param>  
</filter>  

II . 同時Spring還為我們提供了另一種方案,就是使用攔截器,但偶還不太知道怎麽配的,配的沒有成功。還有這裏需要用到spring-mvc.jar,不在spring.jar裏面。還聽說這個使用這個攔截器會有一些bug,偶現在也不知道到底是怎麽個情況,有高人請指點。

技術分享

技術分享

關於Hibernate懶加載問題的最終解決方案