6 Replies Latest reply on May 23, 2011 4:27 PM by Mark Torres

    Jbpm transaction rollback problem

    Mark Torres Newbie

      I'm having problem when an exception is raised in one of the action handlers of my jpdl process. The changes made through the seam managed hibernate session gets rolled back, but changes made in jbpm session gets flushed/commited.


      I'm using the same sessionfactory for both jbpm and my app. While doing the debug, even with rollbacks being set after the exception was thrown, jbpmContext.close() gets called during destroy of ManagedJmbpmContext, which cause jbpm's session to flush.


      Would anyone be able to guide me on how to fix this issue?


      hibernate.properties


      hibernate.show_sql=true
      hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
      hibernate.hbm2ddl.auto=update
      
      hibernate.connection.datasource=java:/prototypeDS
      hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
      
      hibernate.transaction.factory_class=org.hibernate.transaction.JDBCTransactionFactory
      hibernate.transaction.flush_before_completion=true
      


      jbpm.cfg.xml, com.rfc.util.seam.jbpm.SeamSessionFactory is a class that gets the SessionFactory from seam.



      <jbpm-configuration>  
      
        <bean name="seamSessionFactoryCreator" 
               class="com.rfc.util.seam.jbpm.SeamSessionFactory" 
               singleton="true"/>                
        
        <bean name="seamSessionFactory" 
               class="org.hibernate.SessionFactory" 
               singleton="true">
              <constructor factory="seamSessionFactoryCreator" method="getSessionFactory" >
                 <parameter class="java.lang.String">
                   <string>hibernateSessionFactory</string>
                 </parameter>                
                   </constructor>         
        </bean>      
         
        <jbpm-context>
          <service name="persistence">
             <factory>
                <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
                   <field name="isTransactionEnabled"><false/></field>
                    <property name="sessionFactory">
                           <ref bean="seamSessionFactory" />            
                    </property>             
                </bean>
             </factory>
          </service>
          <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
          <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
          <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
          <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
          <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
        </jbpm-context>
      </jbpm-configuration>



        • 1. Re: Jbpm transaction rollback problem
          Mark Torres Newbie

          Is this a bug? There's a similar issue on this post http://www.seamframework.org/Community/SeamJBPMTransactions.


          I searched in Seam's JIRA, there's no issue filed for it yet.

          • 2. Re: Jbpm transaction rollback problem
            Mark Torres Newbie

            I did some more digging into this. I'm using Seam with pojo and plain hibernate, no EJBs.


            The main issue I found was even after rollback is called, ManagedJbpmContext.afterCompletion does not really do anything because the EventContext is still active. Later on during ManagedJbpmContext.destroy, the jbpmContext is closed and those changes that are stored in autoSave are still flushed.


            To get around this problem, I overrode ManagedJbpmContext with an implementation that tries to clear and replace the managed jbpmContext during rollback. The method is shown below. SeamAwareDbPersistenceService is just a subclass of DbPersistenceService that exposes mustSessionBeFlushed to public, this is set to false during a rollback. Error still happens during the call to jbpmContext.close when jbpmContext tries to call autoSave, I have not found a way to clear this from jbpmContext.


            public void afterCompletion(int status) {
                 synchronizationRegistered = false;
                 if (status == Status.STATUS_ROLLEDBACK) {
                 // dont flush the session, clear it.
                 SeamAwareDbPersistenceService dbps = (SeamAwareDbPersistenceService) jbpmContext
                      .getServices().getPersistenceService();
                      if (dbps.getSession() != null) {
                           dbps.getSession().clear();
                      }               
                      dbps.setMustSessionBeFlushed(false);
                      try {
                           jbpmContext.close();
                      } catch (Throwable t) {
                           //error still happens because of 
                           //jbpmContext trying to run autoSave.
                           //this should be cleared.
                           log.warn("Error closing jbpmContext.", t);
                      } finally {
                           jbpmContext = Jbpm.instance().getJbpmConfiguration()
                                .createJbpmContext();
                      }
                 }
            
                 if (!Contexts.isEventContextActive()) {
                      // in calls to MDBs and remote calls to SBs, the
                      // transaction doesn't commit until after contexts
                      // are destroyed, so wait until the transaction
                      // completes before closing the session
                      // on the other hand, if we still have an active
                      // event context, leave it open
                      closeContext();
                 }
            }



            Aside from this, I used JTATransaction strategy on my hibernate.properties.


            hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory
            hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup
            hibernate.transaction.flush_before_completion=true



            Please let me know if this can cause some unforseen problems. Should ManagedJbpmContext be clearing the jbpmContext during rollback?


            I appreciate your insight into this.

            • 3. Re: Jbpm transaction rollback problem
              Lukasz Kwiatkowski Newbie

              I have exactly the same problem with SEAM 2.1.1. Have You found other solution to this.

              • 4. Re: Jbpm transaction rollback problem
                Mark Torres Newbie

                No, I ended up using this approach of overriding ManagedJbpmContext. In addition to the above code, I had to replace



                try {
                     jbpmContext.close();
                } catch (Throwable t) {
                     //error still happens because of 
                     //jbpmContext trying to run autoSave.
                     //this should be cleared.
                     log.warn("Error closing jbpmContext.", t);
                } finally {
                     jbpmContext = Jbpm.instance().getJbpmConfiguration()
                          .createJbpmContext();
                }



                with the code below to clear the autosave items from JbpmContext. If you find an alternative solution, please let me know.



                try {
                     JbpmUtils.clearAndClose(jbpmContext);
                } catch (Throwable t) {
                     //error still happens because of 
                     //jbpmContext trying to run autoSave.
                     //this should be cleared.
                     log.warn("Error closing jbpmContext.", t);
                } finally {
                     jbpmContext = Jbpm.instance().getJbpmConfiguration()
                               .createJbpmContext();
                }





                package org.jbpm;
                public class JbpmUtils {
                     private JbpmUtils(){          
                     }
                     
                     public static void clearAndClose(JbpmContext context){
                          if (context.autoSaveProcessInstances!=null)
                               context.autoSaveProcessInstances.clear();
                          context.close();
                     }
                }



                • 5. Re: Jbpm transaction rollback problem
                  Jinping Zheng Newbie

                  Mark,


                  I have same issue with jboss seam 2.2.1.CR3 and 2.2.2.Final. I could not find any solution right now. I also tried your approach and got a null point and conversation concurrent access errors. See below. Can you post your final solution? if you still override the class ManagedJbpmContext, please post the whole java file, the hibernate.cfg.xml, jbpm.cfg.xml. the transaction type defined in the component.xml, the conversation scope, transaction type, etc. If you have a small working sample, it would be great. Thanks,



                  exception


                  java.lang.NullPointerException
                       org.jboss.seam.bpm.BusinessProcess.hasActiveProcess(BusinessProcess.java:64)
                       org.jboss.seam.contexts.Contexts.flushAndDestroyContexts(Contexts.java:347)
                       org.jboss.seam.contexts.Lifecycle.endRequest(Lifecycle.java:164)
                       org.jboss.seam.web.ExceptionFilter.endWebRequestAfterException(ExceptionFilter.java:89)
                       org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:70)
                       org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                       org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
                       org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                       org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
                       org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
                       org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
                       org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
                       org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
                       org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                       org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
                       org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                       org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
                       org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)


                  • 6. Re: Jbpm transaction rollback problem
                    Mark Torres Newbie

                    What is causing the NullPointerException(which field/variable is null)? I suggest adding an exception breakpoint on NullPointerException to see which is the actual code that's causing it.


                    Anyway, here are the code I used. Its been working for us on seam 2.1.2.GA, and jbpm 3.2.5.GA. I removed the package information. Also, we're using a transactional cache, hence its declared like that on hibernate.cfg.xml, pls change according to your environment.



                    Custom Managed Jbpm context


                    import javax.naming.NamingException;
                    import javax.transaction.RollbackException;
                    import javax.transaction.Status;
                    import javax.transaction.SystemException;
                    
                    import org.jboss.seam.Component;
                    import org.jboss.seam.ScopeType;
                    import org.jboss.seam.annotations.Create;
                    import org.jboss.seam.annotations.Destroy;
                    import org.jboss.seam.annotations.Install;
                    import org.jboss.seam.annotations.Name;
                    import org.jboss.seam.annotations.Scope;
                    import org.jboss.seam.annotations.Unwrap;
                    import org.jboss.seam.annotations.intercept.BypassInterceptors;
                    import org.jboss.seam.bpm.BusinessProcess;
                    import org.jboss.seam.bpm.Jbpm;
                    import org.jboss.seam.bpm.ManagedJbpmContext;
                    import org.jboss.seam.contexts.Contexts;
                    import org.jboss.seam.contexts.Lifecycle;
                    import org.jboss.seam.log.LogProvider;
                    import org.jboss.seam.log.Logging;
                    import org.jboss.seam.transaction.Transaction;
                    import org.jboss.seam.transaction.UserTransaction;
                    import org.jbpm.JbpmContext;
                    import org.jbpm.JbpmUtils;
                    import org.jbpm.persistence.db.DbPersistenceServiceFactory;
                    import org.jbpm.svc.Services;
                    
                    /**
                     * This class overrides ManagedJbpmContext in that it tracks rollbacks caused by unhandled exceptions on jbpmHandlers.
                     * See http://www.seamframework.org/Community/JbpmTransactionRollbackProblem for more details.
                     * The logic that was changed was
                     * 1. During a rollback operation, the managed jbpmContext is cleared and replaced with a new one.
                     * 
                     * This implementation has been tested on JTATransaction.
                     * 
                     * @author mtorres
                     * 
                     */
                    @Scope(ScopeType.EVENT)
                    @Name("org.jboss.seam.bpm.jbpmContext")
                    @BypassInterceptors
                    @Install(dependencies = "org.jboss.seam.bpm.jbpm",precedence=Install.FRAMEWORK)
                    public class TxManagedJbpmContext extends ManagedJbpmContext {
                         private static final LogProvider log = Logging
                                   .getLogProvider(ManagedJbpmContext.class);
                    
                         private JbpmContext jbpmContext;
                         private boolean synchronizationRegistered;
                    
                         @Create
                         public void create() throws NamingException, RollbackException,
                                   SystemException {
                              jbpmContext = Jbpm.instance().getJbpmConfiguration()
                                        .createJbpmContext();
                              assertNoTransactionManagement();
                              log.debug("created seam managed jBPM context");
                         }
                    
                         private void assertNoTransactionManagement() {
                              DbPersistenceServiceFactory dpsf = (DbPersistenceServiceFactory) jbpmContext
                                        .getJbpmConfiguration().getServiceFactory(
                                                  Services.SERVICENAME_PERSISTENCE);
                              if (dpsf.isTransactionEnabled()) {
                                   throw new IllegalStateException(
                                             "jBPM transaction management is enabled, disable in jbpm.cfg.xml");
                              }
                         }
                    
                         @Unwrap
                         public JbpmContext getJbpmContext() throws NamingException,
                                   RollbackException, SystemException {
                              joinTransaction();
                              return jbpmContext;
                         }
                    
                         private void joinTransaction() throws SystemException {
                              UserTransaction transaction = Transaction.instance();
                    
                              if (!transaction.isActiveOrMarkedRollback()) {
                                   throw new IllegalStateException(
                                             "JbpmContext may only be used inside a transaction");
                              }
                    
                              if (!synchronizationRegistered && !Lifecycle.isDestroying()
                                        && transaction.isActive()) {
                                   jbpmContext.getSession().isOpen();
                                   try // TODO: what we really want here is if (!cmt)
                                   {
                                        transaction.registerSynchronization(this);
                                   } catch (UnsupportedOperationException uoe) {
                                        jbpmContext.getSession().getTransaction()
                                                  .registerSynchronization(this);
                                   }
                                   synchronizationRegistered = true;
                              }
                         }
                    
                         public void beforeCompletion() {
                              log.debug("flushing seam managed jBPM context");
                              /*
                               * org.jbpm.graph.exe.ProcessInstance processInstance =
                               * ProcessInstance.instance(); if (processInstance!=null) {
                               * jbpmContext.save(processInstance); }
                               */
                              if (Contexts.isBusinessProcessContextActive()) {
                                   // in requests that come through SeamPhaseListener,
                                   // transactions are committed before the contexts are
                                   // destroyed, flush here:
                                   Contexts.getBusinessProcessContext().flush();
                              }
                              jbpmContext.getSession().flush();
                              log.debug("done flushing seam managed jBPM context");
                         }
                    
                         public void afterCompletion(int status) {
                              synchronizationRegistered = false;
                              if (status == Status.STATUS_ROLLEDBACK) {
                                   log.warn("This is an override to default behaviour of ManagedJbpmContext, " +
                                             " during a rollback operation, we want to clear jbpmContext's " +
                                             " autosave cache so it does not get flushed during the destroy phase. " +
                                             " This method also replaces the managedJbpmContext with a new one." +
                                             " See http://www.seamframework.org/Community/JbpmTransactionRollbackProblem " +
                                             " for more details. ");
                                   // dont flush the session, clear it.
                                   SeamAwareDbPersistenceService dbps = (SeamAwareDbPersistenceService) jbpmContext
                                             .getServices().getPersistenceService();
                                   if (dbps.getSession() != null) {
                                        dbps.getSession().clear();
                                   }               
                                   dbps.setMustSessionBeFlushed(false);
                                   try {
                                        JbpmUtils.clearAndClose(jbpmContext);
                                   } catch (Throwable t) {
                                        //error still happens because of 
                                        //jbpmContext trying to run autoSave.
                                        //this should be cleared.
                                        log.warn("Error closing jbpmContext.", t);
                                   } finally {
                                        jbpmContext = Jbpm.instance().getJbpmConfiguration()
                                                  .createJbpmContext();
                                        if (BusinessProcess.instance().getProcessId()!=null && jbpmContext.getProcessInstance(BusinessProcess.instance().getProcessId())==null){
                                             BusinessProcess.instance().setProcessId(null);
                                        }
                                        if (BusinessProcess.instance().getTaskId()!=null && jbpmContext.getTaskInstance(BusinessProcess.instance().getTaskId())==null){
                                             BusinessProcess.instance().setTaskId(null);
                                        }
                                   }
                              }
                    
                              if (!Contexts.isEventContextActive()) {
                                   // in calls to MDBs and remote calls to SBs, the
                                   // transaction doesn't commit until after contexts
                                   // are destroyed, so wait until the transaction
                                   // completes before closing the session
                                   // on the other hand, if we still have an active
                                   // event context, leave it open
                                   closeContext();
                              }
                         }
                    
                         @Destroy
                         public void destroy() {
                              if (!synchronizationRegistered) {
                                   // in requests that come through SeamPhaseListener,
                                   // there can be multiple transactions per request,
                                   // but they are all completed by the time contexts
                                   // are dstroyed
                                   // so wait until the end of the request to close
                                   // the session
                                   // on the other hand, if we are still waiting for
                                   // the transaction to commit, leave it open
                                   closeContext();
                              }
                         }
                    
                         private void closeContext() {
                              log.debug("destroying seam managed jBPM context");
                              jbpmContext.close();
                              log.debug("done destroying seam managed jBPM context");
                         }
                    
                         public static JbpmContext instance() {
                              if (!Contexts.isEventContextActive()) {
                                   throw new IllegalStateException("no active event context");
                              }
                              return (JbpmContext) Component.getInstance(ManagedJbpmContext.class,
                                        ScopeType.EVENT);
                         }
                    }




                    Custom DbPersistenceService




                    import java.sql.Connection;
                    
                    import org.hibernate.EmptyInterceptor;
                    import org.hibernate.Session;
                    import org.jbpm.persistence.db.DbPersistenceService;
                    import org.jbpm.persistence.db.DbPersistenceServiceFactory;
                    
                    /**
                     * DbPersistenceService that exposes mustSessionBeFlushed.
                     * 
                     * @author mtorres
                     * 
                     */
                    @SuppressWarnings("serial")
                    public class SeamAwareDbPersistenceService extends DbPersistenceService {
                         public SeamAwareDbPersistenceService(
                                   DbPersistenceServiceFactory persistenceServiceFactory) {
                              super(persistenceServiceFactory);
                         }
                    
                         public void setMustSessionBeFlushed(boolean val) {
                              mustSessionBeFlushed = val;
                         }
                    
                         /*
                          * (non-Javadoc)
                          * 
                          * @see org.jbpm.persistence.db.DbPersistenceService#getSession()
                          */
                         @Override
                         public Session getSession() {
                              if ((session == null) && (getSessionFactory() != null)) {
                                   Connection connection = getConnection(false);
                                   if (isCurrentSessionEnabled) {
                                        session = getSessionFactory().getCurrentSession();
                                        mustSessionBeClosed = false;
                                        mustSessionBeFlushed = false;
                                        mustConnectionBeClosed = false;
                                   } else if (connection != null) {
                                        session = getSessionFactory().openSession(connection);
                                        mustSessionBeClosed = true;
                                        mustSessionBeFlushed = true;
                                        mustConnectionBeClosed = false;
                                   } else {
                                        /**
                                         * Sets session to have an empty interceptor. The HibernateSecurityInterceptor
                                         * attached to sessionfactory causes problems for timers.
                                         */
                                        session = getSessionFactory().openSession(new EmptyInterceptor(){});
                                        mustSessionBeClosed = true;
                                        mustSessionBeFlushed = true;
                                        mustConnectionBeClosed = false;
                                   }
                    
                                   if (isTransactionEnabled) {
                                        beginTransaction();
                                   }
                              }
                              
                              /**
                               * Override to fix https://jira.jboss.org/jira/browse/JBPM-1775 Recent
                               * changes to jbpm(starting from 3.2.3), which sets lazy=false on
                               * exception handlers, cause transaction exceptions to be thrown from
                               * GraphElement.findExceptionHandler. This code tricks,
                               * GraphElement.isAbleToHandleExceptions to return false, when a
                               * rollback has occured.
                               */
                              transaction = session.getTransaction();
                              return session;
                         }
                    }




                    Custom DBPersistenceServiceFactory





                    public class SeamAwareDbPersistenceFactory extends DbPersistenceServiceFactory{          
                         
                         /* (non-Javadoc)
                          * @see org.jbpm.persistence.db.DbPersistenceServiceFactory#openService()
                          */
                         @Override
                         public Service openService() {
                              return new SeamAwareDbPersistenceService(this);
                         }
                    }






                    jbpm.cfg.xml





                    <jbpm-configuration>
                      <!-- To create a new session factory from a different file. -->       
                      <!-- 
                      <string name="resource.hibernate.cfg.xml" value="jbpm-hibernate.cfg.xml" />
                       -->     
                      
                      <!-- To use a factory to obtain the sessionFactory from seam. -->
                      <bean name="seamSessionFactoryCreator" 
                             class="SeamSessionFactory" 
                             singleton="true"/>                
                      
                      <bean name="seamSessionFactory" 
                             class="org.hibernate.SessionFactory" 
                             singleton="true">
                            <constructor factory="seamSessionFactoryCreator" method="getSessionFactory" >
                               <parameter class="java.lang.String">
                                 <string>hibernateSessionFactory</string>
                               </parameter>                
                                 </constructor>         
                      </bean>      
                       
                      <jbpm-context>
                        <service name="persistence">
                           <factory>
                              <bean class="SeamAwareDbPersistenceFactory">
                                 <field name="isTransactionEnabled"><false/></field>
                                 <!-- To use a JNDI for the sessionFactory. -->     
                                 <!--         
                                 <field name="sessionFactoryJndiName"><string>java:/dbSession</string></field>
                                  -->
                                  <property name="sessionFactory">
                                         <ref bean="seamSessionFactory" />            
                                  </property>             
                              </bean>
                           </factory>
                        </service>
                        <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
                        <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
                        <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
                        <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
                        <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
                      </jbpm-context>  
                    </jbpm-configuration>






                    import org.hibernate.SessionFactory;
                    import org.jboss.seam.Component;
                    
                    /**
                     * Factory class that returns the SessionFactory configured in Seam. This can used in jbpm.cfg.xml to
                     * inject seam's SessionFactory into jbpm.
                     * @author mtorres
                     *
                     */
                    public class SeamSessionFactory {
                         public static SessionFactory getSessionFactory(String name){
                              if (name==null){
                                   name = "hibernateSessionFactory";
                              }
                              return (SessionFactory)Component.getInstance(name);
                         }
                    }





                    hibernate.cfg.xml




                    <!DOCTYPE hibernate-configuration PUBLIC
                         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
                    
                    <hibernate-configuration>
                        <session-factory>
                             
                              
                       <!-- ###################### -->
                       <!-- # jbpm mapping files # -->
                       <!-- ###################### -->
                            
                             <!-- ############################################ -->
                             <!-- # mapping files with external dependencies # -->
                             <!-- ############################################ -->
                         
                             <!-- Additional mappings defined per module go here -->
                             <!-- 
                             <mapping resource="hibernate.extra.hbm.xml" />
                             <mapping resource="hibernate.identity.hbm.xml" />
                               -->
                               
                            <!-- hql queries and type defs -->
                            <mapping resource="org/jbpm/db/hibernate.queries.hbm.xml" />
                            <!-- hql queries used in simulation for querying historical data
                                 uncomment if you want to use the GetSimulationInputCommand
                                 or maybe you also want to use the queries yourself
                                 be patient: the queries need the stddev function to be enabled in your dialect
                                 more information on this can be found here: http://www.camunda.com/business_process_simulation_news/mysql_and_stddev.html -->
                            <!--
                            <mapping resource="org/jbpm/sim/bam/hibernate.queries.hbm.xml" />
                            -->
                         
                            <!-- graph.action mapping files -->
                            <mapping resource="org/jbpm/graph/action/MailAction.hbm.xml"/>
                         
                            <!-- graph.def mapping files -->
                            <mapping resource="org/jbpm/graph/def/ProcessDefinition.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/def/Node.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/def/Transition.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/def/Event.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/def/Action.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/def/SuperState.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/def/ExceptionHandler.hbm.xml"/>
                            <mapping resource="org/jbpm/instantiation/Delegation.hbm.xml"/>
                         
                            <!-- ############################################ -->
                            <!-- # another mapping file with external dependencies # -->
                            <!-- ############################################ -->
                            <!-- following mapping file has a dependency on   -->
                            <!-- 'bsh-{version}.jar'.                         -->
                            <!-- uncomment this if you don't have bsh on your -->
                            <!-- classpath.  you won't be able to use the     -->
                            <!-- script element in process definition files   -->
                            <!-- has to be defined below org/jbpm/graph/def/Action.hbm.xml -->
                            <!-- due to the inline collection-cache elements below -->
                            <mapping resource="org/jbpm/graph/action/Script.hbm.xml"/>
                         
                            <!-- graph.node mapping files -->
                            <mapping resource="org/jbpm/graph/node/StartState.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/node/EndState.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/node/ProcessState.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/node/Decision.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/node/Fork.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/node/Join.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/node/MailNode.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/node/State.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/node/TaskNode.hbm.xml"/>
                         
                            <!-- context.def mapping files -->
                            <mapping resource="org/jbpm/context/def/ContextDefinition.hbm.xml"/>
                            <mapping resource="org/jbpm/context/def/VariableAccess.hbm.xml"/>
                         
                            <!-- bytes mapping files -->
                            <mapping resource="org/jbpm/bytes/ByteArray.hbm.xml"/>
                         
                            <!-- module.def mapping files -->
                            <mapping resource="org/jbpm/module/def/ModuleDefinition.hbm.xml"/>
                         
                            <!-- file.def mapping files -->
                            <mapping resource="org/jbpm/file/def/FileDefinition.hbm.xml"/>
                         
                            <!-- taskmgmt.def mapping files -->
                            <mapping resource="org/jbpm/taskmgmt/def/TaskMgmtDefinition.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/def/Swimlane.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/def/Task.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/def/TaskController.hbm.xml"/>
                         
                            <!-- scheduler.def mapping files -->
                            <mapping resource="org/jbpm/scheduler/def/CreateTimerAction.hbm.xml"/>
                            <mapping resource="org/jbpm/scheduler/def/CancelTimerAction.hbm.xml"/>
                         
                            <!-- graph.exe mapping files -->
                            <mapping resource="org/jbpm/graph/exe/Comment.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/exe/ProcessInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/exe/Token.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/exe/RuntimeAction.hbm.xml"/>
                         
                            <!-- module.exe mapping files -->
                            <mapping resource="org/jbpm/module/exe/ModuleInstance.hbm.xml"/>
                         
                            <!-- context.exe mapping files -->
                            <mapping resource="org/jbpm/context/exe/ContextInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/TokenVariableMap.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/VariableInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/variableinstance/ByteArrayInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/variableinstance/DateInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/variableinstance/DoubleInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/variableinstance/HibernateLongInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/variableinstance/HibernateStringInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/variableinstance/LongInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/variableinstance/NullInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/context/exe/variableinstance/StringInstance.hbm.xml"/>
                         
                            <!-- job mapping files -->
                            <mapping resource="org/jbpm/job/Job.hbm.xml"/>
                            <mapping resource="org/jbpm/job/Timer.hbm.xml"/>
                            <mapping resource="org/jbpm/job/ExecuteNodeJob.hbm.xml"/>
                            <mapping resource="org/jbpm/job/ExecuteActionJob.hbm.xml"/>
                            <mapping resource="org/jbpm/job/CleanUpProcessJob.hbm.xml"/>
                         
                            <!-- taskmgmt.exe mapping files -->
                            <mapping resource="org/jbpm/taskmgmt/exe/TaskMgmtInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/exe/TaskInstance.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/exe/PooledActor.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/exe/SwimlaneInstance.hbm.xml"/>
                         
                            <!-- logging mapping files -->
                            <mapping resource="org/jbpm/logging/log/ProcessLog.hbm.xml"/>
                            <mapping resource="org/jbpm/logging/log/MessageLog.hbm.xml"/>
                            <mapping resource="org/jbpm/logging/log/CompositeLog.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/log/ActionLog.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/log/NodeLog.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/log/ProcessInstanceCreateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/log/ProcessInstanceEndLog.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/log/ProcessStateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/log/SignalLog.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/log/TokenCreateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/log/TokenEndLog.hbm.xml"/>
                            <mapping resource="org/jbpm/graph/log/TransitionLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/VariableLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/VariableCreateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/VariableDeleteLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/VariableUpdateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/variableinstance/ByteArrayUpdateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/variableinstance/DateUpdateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/variableinstance/DoubleUpdateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/variableinstance/HibernateLongUpdateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/variableinstance/HibernateStringUpdateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/variableinstance/LongUpdateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/context/log/variableinstance/StringUpdateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/log/TaskLog.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/log/TaskCreateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/log/TaskAssignLog.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/log/TaskEndLog.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/log/SwimlaneLog.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/log/SwimlaneCreateLog.hbm.xml"/>
                            <mapping resource="org/jbpm/taskmgmt/log/SwimlaneAssignLog.hbm.xml"/>
                         
                           <!-- ################################### -->
                           <!-- # cache settings                  # -->
                           <!-- # strategy="nonstrict-read-write" # -->
                           <!-- # can be used with hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider # -->
                           <!-- ################################### -->
                           
                           <class-cache class="org.jbpm.context.def.VariableAccess" usage="transactional" />
                           
                           <collection-cache collection="org.jbpm.file.def.FileDefinition.processFiles" usage="transactional" />
                           
                           <collection-cache collection="org.jbpm.graph.action.Script.variableAccesses" usage="transactional" />
                           
                           <class-cache class="org.jbpm.graph.def.Action" usage="transactional" />
                           
                           <class-cache class="org.jbpm.graph.def.Event" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.Event.actions" usage="transactional" />
                           
                           <class-cache class="org.jbpm.graph.def.ExceptionHandler" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.ExceptionHandler.actions" usage="transactional" />
                           
                           <class-cache class="org.jbpm.graph.def.Node" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.Node.events" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.Node.exceptionHandlers" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.Node.leavingTransitions" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.Node.arrivingTransitions" usage="transactional" />
                           
                           <class-cache class="org.jbpm.graph.def.ProcessDefinition" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.ProcessDefinition.events" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.ProcessDefinition.exceptionHandlers" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.ProcessDefinition.nodes" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.ProcessDefinition.actions" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.ProcessDefinition.definitions" usage="transactional" />
                           
                           <collection-cache collection="org.jbpm.graph.def.SuperState.nodes" usage="transactional" />
                           
                           <class-cache class="org.jbpm.graph.def.Transition" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.Transition.events" usage="transactional" />
                           <collection-cache collection="org.jbpm.graph.def.Transition.exceptionHandlers" usage="transactional" />
                           
                           <collection-cache collection="org.jbpm.graph.node.Decision.decisionConditions" usage="transactional" />
                           
                           <collection-cache collection="org.jbpm.graph.node.ProcessState.variableAccesses" usage="transactional" />
                           
                           <collection-cache collection="org.jbpm.graph.node.TaskNode.tasks" usage="transactional" />
                           
                           <class-cache class="org.jbpm.instantiation.Delegation" usage="transactional" />
                           
                           <class-cache class="org.jbpm.module.def.ModuleDefinition" usage="transactional" />
                           
                           <collection-cache collection="org.jbpm.taskmgmt.def.Swimlane.tasks" usage="transactional" />
                           
                           <class-cache class="org.jbpm.taskmgmt.def.TaskController" usage="transactional" />
                           <collection-cache collection="org.jbpm.taskmgmt.def.TaskController.variableAccesses" usage="transactional" />
                           
                           <class-cache class="org.jbpm.taskmgmt.def.Task" usage="transactional" />
                           <collection-cache collection="org.jbpm.taskmgmt.def.Task.events" usage="transactional" />
                           <collection-cache collection="org.jbpm.taskmgmt.def.Task.exceptionHandlers" usage="transactional" />
                           
                           <collection-cache collection="org.jbpm.taskmgmt.def.TaskMgmtDefinition.swimlanes" usage="transactional" />
                           <collection-cache collection="org.jbpm.taskmgmt.def.TaskMgmtDefinition.tasks" usage="transactional" />
                                       
                         <!-- ###################### -->
                         <!-- # End jbpm mapping files # -->
                         <!-- ###################### -->
                         
                         </session-factory>
                    </hibernate-configuration>
                    



                    hibernate.properties




                    hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
                    
                    #Turn on comments for Interceptor
                    hibernate.use_sql_comments=true
                    
                    #Transaction
                    hibernate.transaction.flush_before_completion=true
                    hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory
                    hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup




                    for components.xml I just made sure that I didnt declare an explicit transaction manager which will cause it to use the JTA transaction manager.