[英]Spring JSF OpenSessionInViewFilter
i'm having big trouble with getting the OpenSessionInViewFilter working, using Spring 3.0.2, hibernate3 and jsf2.我在使用 Spring 3.0.2、hibernate3 和 jsf2 让 OpenSessionInViewFilter 正常工作时遇到了很大的麻烦。
the scenario:场景:
there is a BusinessCaseEntity with holding some simple information properties (of string and int type) and a list of mapped EmployeeEntities.有一个 BusinessCaseEntity 包含一些简单的信息属性(字符串和 int 类型)和映射的 EmployeeEntities 列表。 This list is mapped with
此列表映射为
fetch=FetchType.LAZY fetch=FetchType.LAZY
first of all, i load a list of all BusinessCases and show them in a table.首先,我加载所有 BusinessCases 的列表并将它们显示在表格中。 for this purpose, i use a dao class.
为此,我使用 dao class。 the businesscases with their simple properties are displayed.
显示具有简单属性的商业案例。 if i select a specific businesscase i want to show the connected employees for instance.
例如,如果我 select 是一个特定的商业案例,我想展示相关的员工。 therefore i just want to use the getter method of the businesscase object --> getEmployees()
因此我只想使用商业案例 object --> getEmployees() 的 getter 方法
with my simple understanding of spring and hibernate, i know that the BusinessCaseEntity at this time is detached from any spring and hibernate(session) at the backend and the famous LazyLoadingException appears.根据我对 spring 和 hibernate 的简单了解,我知道此时的 BusinessCaseEntity 与任何 spring 和著名的 LazyLoadingException 分离并出现在后端。
this is where i think that the OpenSessionInViewFilter comes in place.这就是我认为 OpenSessionInViewFilter 到位的地方。 i read a lot of instructions of how to use it, but i still could not manage to get it working in my app.
我阅读了很多关于如何使用它的说明,但我仍然无法让它在我的应用程序中运行。
configured the filter in my web.xml and i made a little subclass of the OpenSessionInViewFilter of spring to do some output for debugging purpose. configured the filter in my web.xml and i made a little subclass of the OpenSessionInViewFilter of spring to do some output for debugging purpose.
nevertheless, when it comes to the point to fetch the required data, the filter opens a new session, then an LazyLoadException is thrown and then the filter closes the session.然而,当涉及到获取所需数据时,过滤器会打开一个新的 session,然后引发 LazyLoadException,然后过滤器会关闭 session。 why is there a LazyLoadException when the session is currently open?
当 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
do i somehow misunderstand the purpose of the OpenSessionInViewFilter?我是否以某种方式误解了 OpenSessionInViewFilter 的目的?
i am quite lost now and would really appreciate some help.我现在很迷茫,非常感谢一些帮助。
thanks - chris谢谢 - 克里斯
I gave up trying to use Spring's OpenSessionInViewFilter.我放弃了尝试使用 Spring 的 OpenSessionInViewFilter。 I have implemented JSF Phase Listeners to do the job, as oriented here: http://assenkolov.blogspot.com.br/2008/04/open-session-in-view-with-jsf-and.html .
I have implemented JSF Phase Listeners to do the job, as oriented here: http://assenkolov.blogspot.com.br/2008/04/open-session-in-view-with-jsf-and.html . The solution worked for me.
该解决方案对我有用。
The full post below (if the link is dead):下面的完整帖子(如果链接已失效):
I expected that a quick google session would immediately deliver the standard solution for this situation, but it didn't go this way.
我希望一个快速的谷歌 session 会立即为这种情况提供标准解决方案,但它没有 go 这种方式。
The problem: I want Open Session in View for an JSF/Spring application.
问题:我想在视图中为 JSF/Spring 应用程序打开 Session。 Ok, I know there is something fishy about open session in view, but believe me, for this application this is just fine.
好的,我知道在视图中打开 session 有一些可疑之处,但相信我,对于这个应用程序来说,这很好。 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.
应用程序有可能最终变成一个 portlet,所以我也不想处理 portlet 和 servlet 过滤器问题。 Instead, I want to use the convenient hooks provided by JSF to open and close the hibernate session - phase listeners.
相反,我想使用 JSF 提供的便捷钩子来打开和关闭 hibernate session - 相位监听器。 Happily, the Spring-provided OpenSessionInViewFilter reveals the technicalities of how Spring deals with the hibernate session factory.
令人高兴的是,Spring 提供的 OpenSessionInViewFilter 揭示了 Spring 如何与 hibernate session 工厂打交道的技术细节。
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:
渲染响应阶段完成后,session 将关闭:
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
不要忘记在 faces-config.xml 中注册监听器
<lifecycle>
<phase-listener>
...HibernateRestoreViewPhaseListener
</phase-listener>
<phase-listener>
...HibernateRenderResponsePhaseListener
</phase-listener>
</lifecycle>
do you have configured a transaction?你有配置交易吗? seehttp://justsomejavaguy.blogspot.com/2010/04/lazy-loading-under-spring.html
见http://justsomejavaguy.blogspot.com/2010/04/lazy-loading-under-spring.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.