org.springframework.orm.jdo.support.OpenPersistenceManagerInViewFilter Maven / Gradle / Ivy
/*
* Copyright 2002-2004 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.jdo.support;
import java.io.IOException;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.orm.jdo.PersistenceManagerFactoryUtils;
import org.springframework.orm.jdo.PersistenceManagerHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* Servlet 2.3 Filter that binds a JDO PersistenceManager to the thread for the
* entire processing of the request. Intended for the "Open PersistenceManager in
* View" pattern, i.e. to allow for lazy loading in web views despite the
* original transactions already being completed.
*
* This filter works similar to the AOP JdoInterceptor: It just makes JDO
* PersistenceManagers available via the thread. It is suitable for
* non-transactional execution but also for middle tier transactions via
* JdoTransactionManager or JtaTransactionManager. In the latter case,
* PersistenceManagers pre-bound by this filter will automatically be used
* for the transactions.
*
*
Looks up the PersistenceManagerFactory in Spring's root web application context.
* Supports a "persistenceManagerFactoryBeanName" filter init-param; the default bean
* name is "persistenceManagerFactory". Looks up the PersistenceManagerFactory on each
* request, to avoid initialization order issues (when using ContextLoaderServlet, the
* root application context will get initialized after this filter).
*
* @author Juergen Hoeller
* @since 1.1
* @see OpenPersistenceManagerInViewInterceptor
* @see org.springframework.orm.jdo.JdoInterceptor
* @see org.springframework.orm.jdo.JdoTransactionManager
* @see org.springframework.orm.jdo.PersistenceManagerFactoryUtils#getPersistenceManager
* @see org.springframework.transaction.support.TransactionSynchronizationManager
*/
public class OpenPersistenceManagerInViewFilter extends OncePerRequestFilter {
public static final String DEFAULT_PERSISTENCE_MANAGER_FACTORY_BEAN_NAME = "persistenceManagerFactory";
private String persistenceManagerFactoryBeanName = DEFAULT_PERSISTENCE_MANAGER_FACTORY_BEAN_NAME;
/**
* Set the bean name of the PersistenceManagerFactory to fetch from Spring's
* root application context. Default is "persistenceManagerFactory".
* @see #DEFAULT_PERSISTENCE_MANAGER_FACTORY_BEAN_NAME
*/
public void setPersistenceManagerFactoryBeanName(String persistenceManagerFactoryBeanName) {
this.persistenceManagerFactoryBeanName = persistenceManagerFactoryBeanName;
}
/**
* Return the bean name of the PersistenceManagerFactory to fetch from Spring's
* root application context.
*/
protected String getPersistenceManagerFactoryBeanName() {
return persistenceManagerFactoryBeanName;
}
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
PersistenceManagerFactory pmf = lookupPersistenceManagerFactory();
PersistenceManager pm = null;
boolean participate = false;
if (TransactionSynchronizationManager.hasResource(pmf)) {
// do not modify the Session: just set the participate flag
participate = true;
}
else {
logger.debug("Opening JDO persistence manager in OpenPersistenceManagerInViewFilter");
pm = PersistenceManagerFactoryUtils.getPersistenceManager(pmf, true);
TransactionSynchronizationManager.bindResource(pmf, new PersistenceManagerHolder(pm));
}
try {
filterChain.doFilter(request, response);
}
finally {
if (!participate) {
TransactionSynchronizationManager.unbindResource(pmf);
logger.debug("Closing JDO persistence manager in OpenPersistenceManagerInViewFilter");
PersistenceManagerFactoryUtils.closePersistenceManagerIfNecessary(pm, pmf);
}
}
}
/**
* Look up the PersistenceManagerFactory that this filter should use.
* The default implementation looks for a bean with the specified name
* in Spring's root application context.
* @return the SessionFactory to use
* @see #getPersistenceManagerFactoryBeanName
*/
protected PersistenceManagerFactory lookupPersistenceManagerFactory() {
logger.info("Using persistence manager factory '" + getPersistenceManagerFactoryBeanName() +
"' for OpenPersistenceManagerInViewFilter");
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
return (PersistenceManagerFactory) wac.getBean(getPersistenceManagerFactoryBeanName());
}
}