2011-06-14 56 views
2

我在使用Spring 3.0.2,hibernate3和jsf2获得OpenSessionInViewFilter工作方面遇到了很大的麻烦。Spring JSF OpenSessionInViewFilter

的情形:

存在与保持一些简单的信息的属性(字符串和INT类型)和映射EmployeeEntities的列表的BusinessCaseEntity。该列表被映射与

取= FetchType.LAZY

首先,我加载所有BusinessCases的列表,并将其显示在表中。为此,我使用了dao类。 显示具有简单属性的业务案例。如果我选择特定的商业案例,例如我想要显示连接的员工。因此我只想使用businesscase对象的getter方法 - > getEmployees()

用我对Spring和Hibernate的简单理解,我知道此时的BusinessCaseEntity与任何spring和hibernate(session)都是分开的,在后端出现着名的LazyLoadingException。

这是我认为OpenSessionInViewFilter到位的地方。我阅读了很多关于如何使用它的说明,但仍然无法在我的应用程序中使用它。

配置我的web.xml中的过滤器,我做了Spring的OpenSessionInViewFilter的一个小的子类来做一些输出用于调试目的。但是,当涉及到获取所需数据的位置时,过滤器会打​​开一个新会话,然后引发LazyLoadException,然后过滤器关闭会话。为什么会话当前打开时会出现LazyLoadException?

2011-06-14 19:19:49,734 DEBUG HibernateFilter:239 - Using SessionFactory 'sessionFactory' for OpenSessionInViewFilter 
2011-06-14 19:19:49,734 DEBUG HibernateFilter:66 - Opening single Hibernate Session in OpenSessionInViewFilter 
Jun 14, 2011 7:19:49 PM com.sun.facelets.FaceletViewHandler handleRenderException 
SEVERE: Error Rendering View[/web/caseDetails.xhtml] 
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.frivak.cat.db.entities.BusinessCaseEntity.caseClientList, no session or session was closed 
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383) 
LOTS OF STACKTRACE ... 
2011-06-14 19:19:49,879 DEBUG HibernateFilter:92 - Closing single Hibernate Session in OpenSessionInViewFilter 

难道我不知何故误解了OpenSessionInViewFilter的目的?

我现在很失落,真的很感谢您的帮助。

谢谢 - chris

回答

0

我放弃了试图使用Spring的OpenSessionInViewFilter。我已经实现了JSF阶段监听器来完成这项工作,如下所示:http://assenkolov.blogspot.com.br/2008/04/open-session-in-view-with-jsf-and.html。该解决方案为我工作。

全文后下方(如果该链接是死的):

我期待一个快速谷歌会议将立即将这种情况的标准解决方案,但它并没有走这条路。

问题:我想在JSF/Spring应用程序的视图中打开会话。好吧,我知道开放会议有点可疑,但相信我,对于这个应用程序来说,这很好。应用程序有可能最终成为portlet,所以我不想处理portlet和servlet过滤器问题。相反,我想使用JSF提供的方便的钩子来打开和关闭hibernate会话 - 阶段监听器。令人高兴的是,Spring提供的OpenSessionInViewFilter揭示了Spring如何处理hibernate会话工厂的技术问题。

下面是结果:

public class HibernateRestoreViewPhaseListener implements PhaseListener { 
    public void afterPhase(PhaseEvent event) { 
} 

protected SessionFactory lookupSessionFactory() { 
    FacesContext context = FacesContext.getCurrentInstance(); 
    ServletContext servletContext = (ServletContext) context.getExternalContext().getContext(); 
    WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(servletContext); 
    return (SessionFactory) wac.getBean("hibernate-session-factory", SessionFactory.class); 
} 

public void beforePhase(PhaseEvent event) { 
    SessionFactory sessionFactory = lookupSessionFactory(); 
    if (!TransactionSynchronizationManager.hasResource(sessionFactory)) { 
     Session session = getSession(sessionFactory); 
     TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); 
    } 
} 

public PhaseId getPhaseId() { 
    return PhaseId.RESTORE_VIEW; 
} 

protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { 
    Session session = SessionFactoryUtils.getSession(sessionFactory, true); 
    session.setFlushMode(FlushMode.MANUAL); 
    return session; 
} 

会话被关闭时,Render Response阶段完成:

public class HibernateRenderResponsePhaseListener implements PhaseListener { 

    public void afterPhase(PhaseEvent event) { 
     SessionFactory sessionFactory = lookupSessionFactory(); 
     SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory); 
     closeSession(sessionHolder.getSession(), sessionFactory); 
    } 

    ... 

} 

不要忘记注册监听器在faces-config.xml中

<lifecycle> 
    <phase-listener> 
     ...HibernateRestoreViewPhaseListener 
    </phase-listener> 
    <phase-listener> 
     ...HibernateRenderResponsePhaseListener 
    </phase-listener> 
</lifecycle>