Spring JSF OpenSessionInViewFilter



我在使用Spring 3.0.2、hibernate3和jsf2使OpenSessionInViewFilter工作时遇到了大麻烦。

场景:

有一个BusinessCaseEntity,它包含一些简单的信息属性(字符串和int类型)和映射的EmployeeEntity列表。此列表与映射

fetch=FetchType.LAZY

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

根据我对spring和hibernate的简单理解,我知道BusinessCaseEntity此时在后端与任何spring和hibernate(会话)分离,并且出现了著名的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

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

下面的完整帖子(如果链接是死的):

我本以为快速的谷歌会议会立即为这种情况提供标准解决方案,但事实并非如此。

问题是:我想要一个JSF/Spring应用程序的OpenSessioninView。好吧,我知道开放会话有一些可疑之处,但相信我,对于这个应用程序来说,这还可以。应用程序最终有可能成为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;
}

当渲染响应阶段结束时,会话将关闭:

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>

您配置了事务吗?看见http://justsomejavaguy.blogspot.com/2010/04/lazy-loading-under-spring.html

相关内容

  • 没有找到相关文章

最新更新