|
From: Matthew E. P. <ma...@po...> - 2003-12-09 01:21:07
|
I am attempting to use the OpenSessionInViewFilter. According to the javadoc, the session is not flush at the end of the filter. Therefore, without overriding the closeSession() method in the filter, how do I get the session to flush? I am currently accessing DAOs wrapped as a ProxyFactoryBean with a HibernateInterceptor. Please help! Cheers, matthew |
|
From: Artem P. <bla...@ca...> - 2005-11-21 01:29:28
|
Some Web application frameworks like JSF might require you to extend the
lifetime of a persistent entity beyond a single HTTP request. What I am
proposing is an alternative implementation of OpenSessionInViewFilter that
opens one Hibernate session per HTTP session instead of one session per
request. JDBC connection management should not be a problem because it is
possible to disconnect and reconnect Hibernate sessions without closing
them.
Here is the filter that I'm using in my application... I think it would be a
good idea to include something similar in a future release of Spring. Please
note that it hasn't been well tested, and it requires a session filter that
closes orphaned sessions.
public class HibernateSessionFilter extends OncePerRequestFilter {
public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME =
"sessionFactory";
public static final String SESSION_KEY = "org.foo.web.hibernateSession";
private String sessionFactoryBeanName = DEFAULT_SESSION_FACTORY_BEAN_NAME;
/**
* @return Returns the sessionFactoryBeanName.
*/
protected String getSessionFactoryBeanName() {
return sessionFactoryBeanName;
}
/**
* @param sessionFactoryBeanName The sessionFactoryBeanName to set.
*/
public void setSessionFactoryBeanName(String sessionFactoryBeanName) {
this.sessionFactoryBeanName = sessionFactoryBeanName;
}
protected SessionFactory lookupSessionFactory() {
if (logger.isDebugEnabled()) {
logger.debug("Using SessionFactory '" + getSessionFactoryBeanName() + "'
for OpenSessionInViewFilter");
}
WebApplicationContext wac =
WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
return (SessionFactory) wac.getBean(getSessionFactoryBeanName(),
SessionFactory.class);
}
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain
filterChain)
throws ServletException, IOException {
SessionFactory sessionFactory = lookupSessionFactory();
HttpSession httpSession = request.getSession();
Session session =
(Session) httpSession.getAttribute(SESSION_KEY);
if (session == null) {
session = sessionFactory.openSession();
httpSession.setAttribute(SESSION_KEY, session);
}
if (!session.isConnected()) {
session.reconnect();
}
TransactionSynchronizationManager.bindResource(sessionFactory, new
SessionHolder(session));
try {
filterChain.doFilter(request, response);
} finally {
TransactionSynchronizationManager.unbindResource(sessionFactory);
session.disconnect();
}
}
}
|
|
From: Les A. H. <le...@ha...> - 2005-11-21 13:24:30
|
It is not recommended to implement this type of behavior in a Hibernate
application. An application-transaction is scoped to a few connected
request/response cycles and shouldn't be used across a user's entire
interaction with the system - doing otherwise creates much greater
conflict for stale data and versioning conflicts.
On Sun, 20 Nov 2005 20:29:21 -0500, "Artem Ploujnikov"
<bla...@ca...> said:
> Some Web application frameworks like JSF might require you to extend
> the
> lifetime of a persistent entity beyond a single HTTP request. What I am
> proposing is an alternative implementation of OpenSessionInViewFilter
> that
> opens one Hibernate session per HTTP session instead of one session per
> request. JDBC connection management should not be a problem because it is
> possible to disconnect and reconnect Hibernate sessions without closing
> them.
>
> Here is the filter that I'm using in my application... I think it would
> be a
> good idea to include something similar in a future release of Spring.
> Please
> note that it hasn't been well tested, and it requires a session filter
> that
> closes orphaned sessions.
>
> public class HibernateSessionFilter extends OncePerRequestFilter {
> public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME =
> "sessionFactory";
> public static final String SESSION_KEY = "org.foo.web.hibernateSession";
>
> private String sessionFactoryBeanName =
> DEFAULT_SESSION_FACTORY_BEAN_NAME;
>
> /**
> * @return Returns the sessionFactoryBeanName.
> */
> protected String getSessionFactoryBeanName() {
> return sessionFactoryBeanName;
> }
>
>
> /**
> * @param sessionFactoryBeanName The sessionFactoryBeanName to set.
> */
> public void setSessionFactoryBeanName(String sessionFactoryBeanName) {
> this.sessionFactoryBeanName = sessionFactoryBeanName;
> }
>
>
> protected SessionFactory lookupSessionFactory() {
> if (logger.isDebugEnabled()) {
> logger.debug("Using SessionFactory '" + getSessionFactoryBeanName() +
> "'
> for OpenSessionInViewFilter");
> }
> WebApplicationContext wac =
> WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
> return (SessionFactory) wac.getBean(getSessionFactoryBeanName(),
> SessionFactory.class);
> }
>
> protected void doFilterInternal(
> HttpServletRequest request, HttpServletResponse response, FilterChain
> filterChain)
> throws ServletException, IOException {
> SessionFactory sessionFactory = lookupSessionFactory();
> HttpSession httpSession = request.getSession();
> Session session =
> (Session) httpSession.getAttribute(SESSION_KEY);
> if (session == null) {
> session = sessionFactory.openSession();
> httpSession.setAttribute(SESSION_KEY, session);
> }
> if (!session.isConnected()) {
> session.reconnect();
> }
> TransactionSynchronizationManager.bindResource(sessionFactory, new
> SessionHolder(session));
> try {
> filterChain.doFilter(request, response);
> } finally {
> TransactionSynchronizationManager.unbindResource(sessionFactory);
> session.disconnect();
> }
>
> }
>
> }
>
>
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by the JBoss Inc. Get Certified Today
> Register for a JBoss Training Course. Free Certification Exam
> for All Training Attendees Through End of 2005. For more info visit:
> http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click
> _______________________________________________
> Springframework-developer mailing list
> Spr...@li...
> https://lists.sourceforge.net/lists/listinfo/springframework-developer
|
|
From: Artem P. <bla...@ca...> - 2005-11-23 23:51:06
|
I am sorry, but I was not subscribed to the mailing list when I posted = my original message regarding the OpenSessionInViewFilter implementation = in Spring. The main reason why I want to store the Hibernate session in the HTTP = session is that in my application, the lifetime of a business objects = exceeds an HTTP request. Furthermore, the application is layered, and = re-attaching all business objects to a new session for every request = would require leaking some Hibernate-specific code into the presentation = layer and/or implementing "reattachment" mechanisms in my business logic = layer. The time it takes to create session objects is immaterial, and I = am not currently concerned about performance at that level. I'm more = concerned about proper layering. I don't want to replace the original filter with the one I'm = proposing... It's just an alternative for applications that require = long-running sessions. Applications that do not use session management = will work just fine with the original filter. The main problem is that = even though Hibernate entities are "just POJOs", they will most likely = contain proxies, and if the original session is closed, they need to be = merge()d with a new session or else they will start throwing exceptions. = Thank you, Artem Ploujnikov |