/*
* Copyright 2002-2006 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 cyrille.hibernate.context;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.context.ThreadLocalSessionContext;
/**
* @author <a href="mailto:cyrille.leclerc@pobox.com">Cyrille Le Clerc</a>
*/
public class DisconnectedSessionOpenInviewFilter implements Filter {
private final static Logger logger = Logger.getLogger(DisconnectedSessionOpenInviewFilter.class);
protected SessionFactory sessionFactory;
public void destroy() {
// sessionFactory will be closed by its creator
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
doFilter(httpServletRequest, httpServletResponse, chain);
}
}
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpSession httpSession = request.getSession(false);
if (httpSession == null) {
logger.debug("No http session found");
} else {
Session session = (Session) httpSession.getAttribute(Session.class.getName());
if (session == null) {
logger.debug("No Hibernate session found in http session");
} else {
// no need to reconnect the session, automatically done by Hibernate
if (logger.isDebugEnabled()) {
logger.debug("Bind " + session + " to ThreadLocalSessionContext");
}
ThreadLocalSessionContext.bind(session);
}
}
try {
// CHAIN
chain.doFilter(request, response);
} finally {
// UNBIND HIBERNATE SESSION FROM HIBERNATE_THREAD_LOCAL_SESSION_CONTEXT, DISCONNECT AND BIND TO HTTP_SESSION
Session session = ThreadLocalSessionContext.unbind(sessionFactory);
if (session == null) {
logger.debug("No Hibernate session unbound by ThreadLocalSessionContext");
} else {
if (session.isDirty()) {
try {
logger.warn("Hibernate session is dirty !");
// TODO what is the policy ? Session will be disconnected and thus modifications will come back during reconnect
if (session.getTransaction().isActive()) {
logger.warn("Rollback active transaction for dirty session");
session.getTransaction().rollback();
}
logger.warn("Close dirty session");
session.close();
} finally {
logger.warn("Remove Hibernate session from http session");
request.getSession().removeAttribute(Session.class.getName());
}
} else {
logger.debug("Hibernate session unbound from ThreadLocalSessionContext, disconnected and bound to http session");
try {
session.disconnect();
// force creation of the HttpSession even if it did not exist at the beginning of the filter
request.getSession().setAttribute(Session.class.getName(), session);
} catch (RuntimeException e) {
logger.error("Exception disconnecting hibernate session. Remove Hibernate session from http session", e);
request.getSession().removeAttribute(Session.class.getName());
throw e;
}
}
}
}
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}