gpt4 book ai didi

hibernate - Spring JSF OpenSessionInViewFilter

转载 作者:行者123 更新时间:2023-12-04 17:20:39 24 4
gpt4 key购买 nike

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

场景:

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

fetch=FetchType.LAZY

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

以我对 spring 和 hibernate 的简单理解,我知道此时的 BusinessCaseEntity 与后端的任何 spring 和 hibernate(session) 是分离的,并且出现了著名的 LazyLoadingException。

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

在我的 web.xml 中配置了过滤器,我创建了 spring 的 OpenSessionInViewFilter 的一个小子类来做一些输出以用于调试目的。

然而,当涉及到获取所需数据时,过滤器会打​​开一个新 session ,然后抛出 LazyLoadException,然后过滤器关闭 session 。为什么 session 当前打开时会出现 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 的目的?

我现在很迷茫,非常感谢一些帮助。

谢谢 - 克里斯

最佳答案

我放弃了尝试使用 Spring 的 OpenSessionInViewFilter。我已经实现了 JSF Phase Listeners 来完成这项工作,如下所示:http://assenkolov.blogspot.com.br/2008/04/open-session-in-view-with-jsf-and.html .该解决方案对我有用。
下面的完整帖子(如果链接已失效):

I expected that a quick google session would immediately deliver the standard solution for this situation, but it didn't go this way.

The problem: I want Open Session in View for an JSF/Spring application. Ok, I know there is something fishy about open session in view, but believe me, for this application this is just fine. There is a chance that the application will become a portlet eventually, so I didn't want to have to handle portlet and servlet filters issues too. Instead, I want to use the convenient hooks provided by JSF to open and close the hibernate session - phase listeners. Happily, the Spring-provided OpenSessionInViewFilter reveals the technicalities of how Spring deals with the hibernate session factory.

Here is the result:

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;
}

The session gets closed when Render Response phase is finished:

public class HibernateRenderResponsePhaseListener implements PhaseListener {

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

...

}

Don't forget to register the listeners in faces-config.xml

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

关于hibernate - Spring JSF OpenSessionInViewFilter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6347842/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com