Thank you for replying.
The classes where this happens are DAO's that access the database through Hibernate and the app in question is a 2.4 webapp.
An HibernateFilter servlet filter starts a session at request start and ends it the the request end (through flter chains)
The outer method from class CategoryDAO starts the session like this:
Code:
public static void OuterUpdate(...) throws Exception
{
Session session = HSessionFactory.createSession();
Transaction transaction = session.beginTransaction();
try {
...
// Calls translationDAO to store a string a return its ID
category.setNameKey(TranslationDAO.update(category.getNameKey(), name));
...
session.saveOrUpdate(category);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}
The inner method from class TranslationDAO :
Code:
public static synchronized String update(...) throws Exception
{
Session session = HSessionFactory.createSession();
Transaction transaction = session.beginTransaction();
try {
...
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}
The HSessionFactory:
Code:
public class HSessionFactory
{
public static Session createSession() throws Exception
{
return HibernateFilter.getSession();
}
}
The hibernate filter
Code:
public class HibernateFilter implements Filter {
public static final String SESSION_FACTORY_KEY = SessionFactory.class
.getName();
protected static final String configFilePath = "/hibernate.cfg.xml";
protected static SessionFactory factory = null;
protected static ThreadLocal hibernateHolder = new ThreadLocal();
private static void initFactory() throws ServletException {
URL configFileURL = HibernateFilter.class
.getResource(configFilePath);
if (configFileURL == null)
throw new ServletException(
"Hibernate config file not found.");
try {
Configuration configuration = new Configuration();
configuration.configure(configFileURL);
factory = configuration.buildSessionFactory();
} catch (Exception e) {
throw new ServletException(e);
}
}
public void init(FilterConfig filterConfig) throws ServletException {
/*
* URL configFileURL =
* HibernateFilter.class.getResource(configFilePath);
*
* if (configFileURL == null) throw new
* ServletException("Hibernate config file not found.");
*
* try { Configuration configuration = new Configuration();
*
* configuration.configure(configFileURL);
*
* factory = configuration.buildSessionFactory(); } catch
* (Exception e) { throw new ServletException(e); }
*/
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (hibernateHolder.get() != null)
throw new IllegalStateException(
"A session is already associated with this thread! "
+ "Someone must have called getSession() outside of the context "
+ "of a servlet request.");
try {
chain.doFilter(request, response);
} finally {
Session sess = (Session) hibernateHolder.get();
if (sess != null) {
hibernateHolder.set(null);
try {
sess.close();
} catch (HibernateException ex) {
throw new ServletException(ex);
}
}
}
}
public static Session getSession() throws Exception {
Session sess = (Session) hibernateHolder.get();
if (sess == null) {
/*
* if (!HibernateFilter.calledWithinRequest())
* System.out.println("----------------- mec
* -----------------");
*/
synchronized (hibernateHolder) {
if (factory == null)
initFactory();
}
Runtime.getRuntime().gc();
sess = factory.openSession();
hibernateHolder.set(sess);
}
return sess;
}
public void destroy() {
}
}