1 Reply Latest reply on Oct 26, 2009 2:27 PM by Ronald van Kuijk

    JBPM / Spring - issue persisting data within thread

    duane mcclure Newbie

      Problem
      We use a thread pool to start workflows so that we do not block our process that kicks off the workflow (FixedThreadPool). Problem is that data being persisted within the actual workflow java task is not being seen outside of the thread that executes the workflow. The workflow java task is a spring bean that has our DAO injected and the DAO is injected with the SessionFactory. If we do not use a thread pool (just start workflow from same thread and block) then everything works fine.

      FYI, I have tried using current="true" with spring-transaction-interceptor (not using job executor) but I get the error - No existing transaction found for transaction marked with propagation 'mandatory'. I've also tried using job executor along with continue="async" in workflow java task instead of using my own thread pool but this produces a NULL pointer exception in org.jbpm.pvm.internal.jobexecutor.JobExecutorMessageSession.send (looked at source and looks like transaction is null for call to transaction.registerSynchronization()).

      I've have spent a good number of hours sifting through the forum, documentation, and source code along with trying various things but have yet to resolve this problem. Configuration details below. Any help is greatly appreciated!

      Environment

      JBPM 4.1, Hibernate 3.3.1, Spring 2.5.6, HSQLDB
      Test Case extending AbstractTransactionalDataSourceSpringContextTests

      JPDL (partial)

      <java expr="#{copyWorkflowTask}" g="50,175,92,52" method="execute" name="copy">
       <arg>
       <object expr="#{execution}"/>
       </arg>
       <transition g="-52,-18" name="to ingestComplete" to="ingestComplete"/>
       </java>
      

      SPRING CONFIG (partial)

       <tx:annotation-driven mode="aspectj" proxy-target-class="false"/>
       <tx:annotation-driven/>
      
       <!-- packages to scan for component DI -->
       <context:component-scan base-package="com.xxx.xxx"/>
      
       <!-- Use Annotation and AspectJ driven transactions -->
       <bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect"
       factory-method="aspectOf"
       lazy-init="false">
      
       <property name="transactionManager" ref="transactionManager"/>
       </bean>
      
       <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
       <constructor-arg>
       <ref local="sessionFactory"/>
       </constructor-arg>
       </bean>
      
       <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
       <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
       <property name="url" value="jdbc:hsqldb:file:latch.db;create=true"/>
       <property name="initialSize" value="1"/>
       <property name="maxActive" value="10"/>
       </bean>
      
       <!-- hibernate session factory -->
       <bean id="sessionFactory"
       class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
       <property name="dataSource">
       <ref local="dataSource"/>
       </property>
       <property name="packagesToScan" value="com.mti.latch.model"/>
       <property name="hibernateProperties">
       <props>
       <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
       <prop key="hibernate.show_sql">false</prop>
       <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
       <prop key="current_session_context_class">thread</prop>
       </props>
       </property>
       <property name="configLocations">
       <list>
       <value>classpath:hibernate.cfg.xml</value>
       </list>
       </property>
       <property name="mappingLocations">
       <list>
       <value>classpath:jbpm.execution.hbm.xml</value>
       <value>classpath:jbpm.repository.hbm.xml</value>
       <value>classpath:jbpm.task.hbm.xml</value>
       <value>classpath:jbpm.history.hbm.xml</value>
       </list>
       </property>
       </bean>
      
       <aop:aspectj-autoproxy/>
      
       <tx:advice id="txAdvice" transaction-manager="transactionManager">
       <tx:attributes>
       <tx:method name="*" propagation="REQUIRED"/>
       </tx:attributes>
       </tx:advice>
      
       <bean id="jbpmConfiguration" class="org.jbpm.pvm.internal.cfg.SpringConfiguration">
       <constructor-arg value="jbpm.cfg.xml"/>
       </bean>
      
       <bean id="processEngine" factory-bean="jbpmConfiguration" factory-method="buildProcessEngine"/>
      
       <!-- handles access to our database -->
       <bean id="coreDao" class="com.xxx.HibernateCoreDao">
       <property name="sessionFactory" ref="sessionFactory"/>
       </bean>
      
       <!-- workflow dao wrapper, wraps calls to JBPM -->
       <bean id="workflowDao" class="com.xxx.JbpmWorkflowDao">
       <property name="processEngine" ref="processEngine"/>
       </bean>
      
       <!-- workflow service wrapper, handles kicking off workflow for a given file -->
       <bean id="ingestWorkflowService" class="com.xxx.IngestWorkflowServiceImpl">
       <property name="coreDao" ref="coreDao"/>
       <property name="workflowKey" value="testInjestProcess"/>
       <property name="workflowDefinition" value="test.injest.jpdl.xml"/>
       <property name="workflowDao" ref="workflowDao"/>
       <constructor-arg value="2"/>
       </bean>
      
       <!-- copy workflow task - called by workflow engine, wraps copy ingestor that
       performs the actual copying of a file -->
       <bean id="copyWorkflowTask" scope="prototype" class="com.xxx.WorkflowTask">
       <property name="baseDirectory" value="target//"/>
       <property name="coreDao" ref="coreDao"/>
       <property name="ingestor" ref="copyIngestor"/>
       <property name="ingestStateTypeValue" value="copying"/>
       </bean>
      
      
       <!-- copy ingestor - handles copying of file -->
       <bean id="copyIngestor" scope="prototype" class="com.xxx.CopyIngestor">
       </bean>
      


      JBPM CONFIG (complete)
       <jbpm-configuration>
       <import resource="jbpm.jpdl.cfg.xml" />
       <import resource="jbpm.identity.cfg.xml" />
      
       <process-engine-context>
       <repository-service />
       <repository-cache />
       <execution-service />
       <history-service />
       <management-service />
       <identity-service />
       <task-service />
      
       <command-service>
       <retry-interceptor />
       <environment-interceptor />
       <spring-transaction-interceptor/>
       </command-service>
      
       <script-manager default-expression-language="juel"
       default-script-language="juel"
       read-contexts="execution, environment, process-engine, spring"
       write-context="">
      
       <script-language name="juel" factory="org.jbpm.pvm.internal.script.JuelScriptEngineFactory" />
       </script-manager>
      
       <id-generator />
       <types resource="jbpm.variable.types.xml" />
       <address-resolver />
       </process-engine-context>
      
       <transaction-context>
       <repository-session />
       <db-session />
       <message-session />
       <timer-session />
       <history-session />
       <mail-session/>
       <hibernate-session current="true" />
       </transaction-context>
       </jbpm-configuration>