Dear Wiki user, You have subscribed to a wiki page or wiki category on "Jakarta-tapestry Wiki" for change notification.
The following page has been changed by HenriDupre: http://wiki.apache.org/jakarta-tapestry/Tapestry4Spring ------------------------------------------------------------------------------ How can you reference Spring beans from Tapestry 4? In earlier versions of Tapestry, the most common method was to extend the BaseEngine class. However, in Tapestry 4 the BaseEngine class is deprecated, and we now need to extend SpringBeanFactoryHolder. (''Basic knowledge of Java, Tapestry, and Spring assumed.'') + + == Spring, Tapestry and Hibernate == + + In order to use lazy loading and for most Spring Hibernate templates, you need access to a Hibernate Session. The traditionnal Spring solution is to use the "OpenSessionInView" pattern where a Hibernate session is open for the whole request. + However, OpenSessionInView has to be configured in the web.xml which is not very friendly when you setup some particular Tapestry URLs. + + A better solution is to integrate the session opening/closing in Hivemind by using the WebRequestServicerFilter interface. Also, for Tapestry assets, it is not necessary to create a session. This code is based on the Spring OpenSessionInViewFilter. + + This requires to implement a class and wire it into Tapestry. + Here is the code for the class: + + {{{ + package actualis.web.tapestry.framework; + + import java.io.IOException; + + import org.apache.commons.logging.Log; + import org.apache.commons.logging.LogFactory; + import org.apache.hivemind.lib.SpringBeanFactoryHolder; + import org.apache.tapestry.Tapestry; + import org.apache.tapestry.services.ServiceConstants; + import org.apache.tapestry.services.WebRequestServicer; + import org.apache.tapestry.services.WebRequestServicerFilter; + import org.apache.tapestry.web.WebRequest; + import org.apache.tapestry.web.WebResponse; + import org.hibernate.FlushMode; + import org.hibernate.Session; + import org.hibernate.SessionFactory; + import org.springframework.dao.DataAccessResourceFailureException; + import org.springframework.orm.hibernate3.SessionFactoryUtils; + import org.springframework.orm.hibernate3.SessionHolder; + import org.springframework.transaction.support.TransactionSynchronizationManager; + + public class HibernateRequestFilter implements WebRequestServicerFilter { + + private static Log logger = LogFactory.getLog(HibernateRequestFilter.class); + + public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory"; + + private String sessionFactoryBeanName = DEFAULT_SESSION_FACTORY_BEAN_NAME; + + private SpringBeanFactoryHolder _beanFactoryHolder; + + /** + * Set the bean name of the SessionFactory to fetch from Spring's root + * application context. Default is "sessionFactory". + * + * @see #DEFAULT_SESSION_FACTORY_BEAN_NAME + */ + public void setSessionFactoryBeanName(String sessionFactoryBeanName) { + this.sessionFactoryBeanName = sessionFactoryBeanName; + } + + /** + * Return the bean name of the SessionFactory to fetch from Spring's root + * application context. + */ + protected String getSessionFactoryBeanName() { + return sessionFactoryBeanName; + } + + public void service(WebRequest request, WebResponse response, + WebRequestServicer servicer) throws IOException { + String svcValue = request.getParameterValue(ServiceConstants.SERVICE); + if (Tapestry.ASSET_SERVICE.equals(svcValue)) { + servicer.service(request, response); + return; + } + logger.debug("entering into Hibernate Request Filter " + " service:" + svcValue + + " context:" + request.getContextPath() + " activation:" + + request.getActivationPath() + " path:" + request.getPathInfo()); + SessionFactory sessionFactory = lookupSessionFactory(request); + Session session = null; + + // single session mode + + logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter"); + session = getSession(sessionFactory); + TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder( + session)); + + try { + servicer.service(request, response); + } + + finally { + // single session mode + TransactionSynchronizationManager.unbindResource(sessionFactory); + logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter"); + try { + closeSession(session, sessionFactory); + } catch (RuntimeException ex) { + logger.error("Unexpected exception on closing Hibernate Session", ex); + } + } + + } + + /** For injection. */ + public final void setBeanFactoryHolder(SpringBeanFactoryHolder beanFactoryHolder) { + _beanFactoryHolder = beanFactoryHolder; + } + + protected SessionFactory lookupSessionFactory(WebRequest request) { + if (logger.isDebugEnabled()) { + logger.debug("Using SessionFactory '" + getSessionFactoryBeanName() + + "' for OpenSessionInViewFilter"); + } + return (SessionFactory) _beanFactoryHolder.getBeanFactory().getBean( + getSessionFactoryBeanName(), SessionFactory.class); + } + + protected Session getSession(SessionFactory sessionFactory) + throws DataAccessResourceFailureException { + return openSession(sessionFactory); + } + + protected Session openSession(SessionFactory sessionFactory) + throws DataAccessResourceFailureException { + Session session = SessionFactoryUtils.getSession(sessionFactory, true); + // session.setFlushMode(FlushMode.NEVER); + session.setFlushMode(FlushMode.COMMIT); + return session; + } + + protected void closeSession(Session session, SessionFactory sessionFactory) { + session.close(); + // SessionFactoryUtils.releaseSession(session, sessionFactory); + } + + } + + }}} + + + The wiring into tapestry is the following: + {{{ + <service-point id="HibernateServicerFilter" + interface="org.apache.tapestry.services.WebRequestServicerFilter"> + <invoke-factory> + <construct class="actualis.web.tapestry.framework.HibernateRequestFilter"> + <set-object property="beanFactoryHolder" value="service:hivemind.lib.DefaultSpringBeanFactoryHolder"/> + </construct> + </invoke-factory> + </service-point> + + <contribution configuration-id="tapestry.request.WebRequestServicerPipeline"> + <filter name="HibernateServicerFilter" + object="service:HibernateServicerFilter"/> + </contribution> + }}} == Step 1: Hivemind Configuration == --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
