0 Replies Latest reply on Sep 21, 2009 7:52 AM by vjger

    OutOfMemoryError at SessionFactory.openSession

    vjger

      Hi.
      I implemented a transaction hibernate-jta architecture into JBoss 4.2.1 and MySql 5 and with hibernate 3.1.

      On a Redhat machine, even with large memory settings on JVM, sometimes the server throws an OutOfMemoryError
      at org.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:535)

      So, these are my relevant classes and methods and configuration file.

      <hibernate-configuration>
       <session-factory name="java:hibernate/SessionFactory">
      
       <property name="hibernate.connection.datasource">java:SicrelDS</property>
       <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
       <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
       <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
       <property name="show_sql">true</property>
      
       <mapping resource="it/lait/sicrel/data/dao/TabErpCrelSeduComm.hbm.xml" />
       </session-factory>
      </hibernate-configuration>
      
      


      public class HibernateTransaction implements TransactionHelper{
       private static Transaction transaction;
      
       public void commitTransaction() throws ProjectException{
       try {
       transaction.commit();
       } catch (Exception e) {
       ProjectLogger.getLogger().error("Errore di commit",e);
       throw new ProjectException(e,"Errore di commit",ProjectException.TypeOfException.HIBERNATE_EXCEPTION);
       }
       }
       public void rollbackTransaction() throws ProjectException{
       try {
       transaction.rollback();
       } catch (Exception e) {
       ProjectLogger.getLogger().error("Errore di rollback",e);
       throw new ProjectException(e,"Errore di rollback",ProjectException.TypeOfException.HIBERNATE_EXCEPTION);
       }
      
       }
      
       public void startTransaction() throws ProjectException{
       try {
       Session session = HibernateSession.getIstance().createSession();
       transaction = session.beginTransaction();
       } catch (Exception e) {
       ProjectLogger.getLogger().error("Errore di beginTransaction",e);
       throw new ProjectException(e,"Errore di beginTransaction",ProjectException.TypeOfException.HIBERNATE_EXCEPTION);
       }
       }
      
       public void endTransaction() throws ProjectException{
       try{
       transaction = null;
       HibernateSession.getIstance().closeSession();
       }catch(Exception e){
       ProjectLogger.getLogger().error("Errore di closeSession",e);
       throw new ProjectException(e,"Errore di closeSession",ProjectException.TypeOfException.HIBERNATE_EXCEPTION);
       }
       }
      }
      
      
      


      public class HibernateSession {
       private static HibernateSession instance;
       private Session session = null;
      
       public static HibernateSession getIstance(){
       if (instance == null) {
       synchronized (HibernateSession.class) {
       if (instance == null) {
       instance = new HibernateSession();
       }
       }
       }
       return instance;
       }
      
      
       /**
       *
       * @return org.hibernate.Session
       */
       public Session createSession() {
       session = HibernateUtil.getSessionFactory().openSession();
       return session;
      
       }
      
       public Session currentSession() {
       return session;
       }
      
       public void closeSession() {
       if (session != null){
       session.close();
       }
       }
      }
      
      


      public class HibernateUtil {
      
       private static Logger log = Logger.getLogger(HibernateUtil.class);
      
       private static final SessionFactory sessionFactory;
       private static final Configuration configuration;
      
       static {
       try {
       // Create the SessionFactory from hibernate.cfg.xml
      
       String hibernateCfgPath = Configurator.getHibernateConfigPath() + "hibernate.cfg.xml";
       String hibernateHbmPath = Configurator.getHibernateConfigPath() + "hbm";
      
       File hibernateFile = new File(hibernateCfgPath);
       configuration = new Configuration().configure(hibernateFile);
       sessionFactory = configuration.buildSessionFactory();
      
       } catch (Throwable ex) {
       // Make sure you log the exception, as it might be swallowed
       log.error("Initial SessionFactory creation failed." /* + Utility.getStackTrace(ex)*/);
       throw new ExceptionInInitializerError(ex);
       }
       }
      
       public static SessionFactory getSessionFactory() {
       return sessionFactory;
       }
      }


      Finally, this is my Business Class

      public class BusinessDispatcher {
      
       private TransactionHelper transaction;
      
       public Command executeCommand(Command command, Strategie strategia) throws ProjectException {
       ProjectLogger.getLogger().debug("Start");
       Strategy strategy = StrategyFactory.getStrategy(strategia, command.getRisorsa());
       Command result = null;
       transaction = new HibernateTransaction();
       try{
       transaction.startTransaction();
       StandardDTO sigemiDTO = command.getRecord();
      
       if(sigemiDTO !=null){
       result = strategy.execute(command);
       }
       transaction.commitTransaction();
       }catch(ProjectException e){
       transaction.rollbackTransaction();
       throw e;
       }catch(Exception e){
       transaction.rollbackTransaction();
       throw new ProjectException(e,ProjectException.TypeOfException.APPLICATION_EXCEPTION);
       }finally{
       transaction.endTransaction();
       }
       ProjectLogger.getLogger().debug("Finish");
       return result;
       }
      }
      
      
      


      and this is the datasource configuration on JBoss

      <datasources>
       <local-tx-datasource>
       <jndi-name>SicrelDS</jndi-name>
       <connection-url>jdbc:mysql://localhost:3306/SICREL?autoReconnect=true</connection-url>
       <driver-class>com.mysql.jdbc.Driver</driver-class>
       <user-name>sicrel</user-name>
       <password>sicrel</password>
       <blocking-timeout-millis>5000</blocking-timeout-millis>
       <min-pool-size>5</min-pool-size>
       <max-pool-size>50</max-pool-size>
       <check-valid-connection-sql>select count(*) from SICREL.TAB_ERP_CREL_USER</check-valid-connection-sql>
       <idle-timeout-minutes>1</idle-timeout-minutes>
       <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
       <metadata>
       <type-mapping>mySQL</type-mapping>
       </metadata>
       </local-tx-datasource>
      
      </datasources>


      Well. On my machine (Windows Vista as OS) works all perfectly and I've not any trouble.
      But, on a Redhat machine, sometimes the server goes into OutOfMemoryError
      at org.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:503)

      This is the complete stacktrace

      java.lang.OutOfMemoryError: PermGen space
       at java.lang.ClassLoader.defineClass1(Native Method)
       at java.lang.ClassLoader.defineClass(ClassLoader.java:637)
       at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
       at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1814)
       at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:872)
       at org.jboss.web.tomcat.service.WebAppClassLoader.findClass(WebAppClassLoader.java:75)
       at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1325)
       at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204)
       at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
       at org.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:503)
       at org.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:527)
       at org.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:535)
       at it.lait.sicrel.web.connector.HibernateSession.createSession(HibernateSession.java:39)
       at it.lait.sicrel.web.connector.HibernateTransaction.startTransaction(HibernateTransaction.java:36)
       at it.lait.sicrel.web.connector.BusinessDispatcher.executeCommand(BusinessDispatcher.java:46)
      



      I would add another information.

      Into the same server an another identical war is deployed (different from the first only for the web.xml).

      I had a trouble because before, into the HibernateUtil class I retrieved the SessionFactory with this code

      
       public static SessionFactory getSessionFactory() {
       try {
       return (SessionFactory)new InitialContext().lookup("java:hibernate/SessionFactory");
       } catch (NamingException e) {
       e.printStackTrace();
       return sessionFactory;
       }
       }
      
      


      So, when the second war invoke this method it has a conflict JNDI Name problem caused by the same JNDI name into the identical hibernate.cfg.xml

      In any case, it seems that without the second war into deploy folder, there aren't OutOfMemoryError(s).



      Any suggest?
      Thanks in advance