-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: OutOfMemory - Many SessionFactoryImpl objects
PostPosted: Fri Jan 16, 2009 4:07 pm 
Newbie

Joined: Fri Jan 16, 2009 12:59 pm
Posts: 2
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:
3.0.3

Name and version of the database you are using:
Oracle 10g

App Server
JBoss 3.2.7

I am seeing a problem in our application with OutOfMemoryException. According to the heap dump, I have 131 SessionFactoryImpl objects all owned by SessionFactoryObjectFactory. I was quite surprised to see this as our code only creates the SessionFactory once within a static initializer block. I was hoping that person someone could help point me in the right direction to find the source of the problem.

We use a web filter to implement the Open Session in View pattern. Below is the code of the filter.

Code:
   public void doFilter(ServletRequest request,
                   ServletResponse response,
                   FilterChain chain)
         throws IOException, ServletException {

      try {
         chain.doFilter(request, response);
         HibernateUtil.commitTransaction();
      } finally {
         HibernateUtil.closeSession();
      }
   }


And the HibernateUtil class:
Code:
public class HibernateUtil {

  private static final Logger LOGGER = Logger.getLogger(HibernateUtil.class);
  private static final LogHelper LOG_HELPER = LogHelper.getInstance();

  private static Configuration configuration;
  private static SessionFactory sessionFactory;
  private static final ThreadLocal threadSession = new ThreadLocal();
  private static final ThreadLocal threadTransaction = new ThreadLocal();
  private static final ThreadLocal threadInterceptor = new ThreadLocal();

  // Create the initial SessionFactory from the default configuration files
  static {
    try {
      configuration = new Configuration();
      sessionFactory = configuration.configure().buildSessionFactory();
    } catch (Throwable ex) {
      LOGGER.error("Building SessionFactory failed.", ex);
      throw new ExceptionInInitializerError(ex);
    }
  }

  /**
   * Returns the SessionFactory used for this static class.
   *
   * @return SessionFactory
   */
  public static SessionFactory getSessionFactory() {
    return sessionFactory;
  }

  /**
   * Returns the original Hibernate configuration.
   *
   * @return Configuration
   */
  private static Configuration getConfiguration() {
    return configuration;
  }

  /**
   * Retrieves the current Session local to the thread.
   * <p/>
   * If no Session is open, opens a new Session for the running thread.
   *
   * @return Session
   */
  public static Session getSession()
  throws InfrastructureException {
    Session s = (Session) threadSession.get();
    try {
      if (s == null) {
        LOGGER.debug("Opening new Session for this thread.");
        if (getInterceptor() != null) {
          LOGGER.debug("Using interceptor: " + getInterceptor().getClass());
          s = getSessionFactory().openSession(getInterceptor());
        } else {
          s = getSessionFactory().openSession();
        }
        threadSession.set(s);
      }
    } catch (HibernateException ex) {
      LOG_HELPER.errorStackTrace(ex, LOGGER) ;
      throw new InfrastructureException(ex);
    }
    return s;
  }

  /**
   * Closes the Session local to the thread.
   */
  public static void closeSession()
  throws InfrastructureException {
    try {
      Session s = (Session) threadSession.get();
      threadSession.set(null);
      if (s != null && s.isOpen()) {
        LOGGER.debug("Closing Session of this thread.");
        s.close();
      }
    } catch (HibernateException ex) {
      LOG_HELPER.errorStackTrace(ex, LOGGER) ;
      throw new InfrastructureException(ex);
    }
  }

  /**
   * Start a new database transaction.
   */
  public static void beginTransaction()
  throws InfrastructureException {
    Transaction tx = (Transaction) threadTransaction.get();
    try {
      if (tx == null) {
        LOGGER.debug("Starting new database transaction in this thread.");
        tx = getSession().beginTransaction();
        threadTransaction.set(tx);
      }
    } catch (HibernateException ex) {
      LOG_HELPER.errorStackTrace(ex, LOGGER) ;
      throw new InfrastructureException(ex);
    }
  }

  /**
   * Commit the database transaction.
   */
  public static void commitTransaction()
  throws InfrastructureException {
    Transaction tx = (Transaction) threadTransaction.get();
    try {
      if ( tx != null && !tx.wasCommitted()
          && !tx.wasRolledBack() ) {
        LOGGER.debug("Committing database transaction of this thread.");
        tx.commit();
      }
      threadTransaction.set(null);
    } catch (HibernateException ex) {
      rollbackTransaction();
      LOG_HELPER.errorStackTrace(ex, LOGGER) ;
      throw new InfrastructureException(ex);
    }
  }

  /**
   * Commit the database transaction.
   */
  public static void rollbackTransaction()
  throws InfrastructureException {
    Transaction tx = (Transaction) threadTransaction.get();
    try {
      threadTransaction.set(null);
      if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) {
        LOGGER.debug("Tyring to rollback database transaction of this thread.");
        tx.rollback();
      }
    } catch (HibernateException ex) {
      LOG_HELPER.errorStackTrace(ex, LOGGER) ;
      throw new InfrastructureException(ex);
    } finally {
      closeSession();
    }
  }

  /**
   * Register a Hibernate interceptor with the current thread.
   * <p>
   * Every Session opened is opened with this interceptor after
   * registration. Has no effect if the current Session of the
   * thread is already open, effective on next close()/getSession().
   */
  public static void registerInterceptor(final Interceptor interceptor) {
    threadInterceptor.set(interceptor);
  }

  private static Interceptor getInterceptor() {
    Interceptor interceptor =
      (Interceptor) threadInterceptor.get();
    return interceptor;
  }
}


Any ideas on why I have so many SessionFactoryImpl instances?


Top
 Profile  
 
 Post subject: OutOfMemory - Many SessionFactoryImpl objects
PostPosted: Fri Jan 16, 2009 5:31 pm 
Newbie

Joined: Fri Jan 16, 2009 12:59 pm
Posts: 2
I found the problem. We also use jbpm within our application. In several of our classes we have static variable holding a reference to JbpmSessionFactory which is created when the class is loaded. JbpmSessionFactory.buildJbpmSessionFactory() creates a Hibernate SessionFactory.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.