3 Replies Latest reply on Oct 3, 2012 4:14 AM by loaone

    Work Item not persisted

    swaminathan.bhaskar

      Hello all;

       

      I am using JPA persistence with jBPM 5.3 with MySQL database. I created a new domain specific task and a corresponding work item handler and expect the work item to be persisted along with the session info as well as process instance info when I kill the process at the point shown in red below ... but do not see that happening. Any ideas or thoughts

       

      Here is the code for the work item handler

       

      public class CustomWorkItemHandler implements WorkItemHandler {

          @Override

          public void executeWorkItem(WorkItem item, WorkItemManager manager) {

              System.out.printf("\n-----> Waiting in custom work item %s <ID:%d> for 60 secs\n", item.getName(), item.getId());

             

              // Expect an entry in the DB for this work item when I kill the process

             

              // Artificial wait

              try {

                  Thread.sleep(60000);

              }

              catch (Exception ex) {

              }

             

              System.out.printf("\n-----> Completing custom work item %s <ID:%d>\n", item.getName(), item.getId());

             

              manager.completeWorkItem(item.getId(), null);

          }

         

          @Override

          public void abortWorkItem(WorkItem item, WorkItemManager manager) {

          }

      }

       

      Here is the main process code:

       

      public class sample07 {

          public static final String BPMN_RESOURCE  = "sample07.bpmn";

          public static final String BPM_PROCESS    = "sample07";

          public static final String WORK_ITEM_NAME = "custom_work_item";

         

          public static final void main(String[] args) {

              if (args.length != 2) {

                  System.out.printf("Usage: java %s <session-id> <process-id>\n", sample07.class.getName());

                  System.exit(1);

              }

             

              try {

                  int sessionId = Integer.parseInt(args[0]);

                  long processId = Long.parseLong(args[1]);

                 

                  // Setup Datasource

                  PoolingDataSource mysqlDS = new PoolingDataSource();

                  mysqlDS.setUniqueName("jdbc/MySQL-DS");

                  mysqlDS.setClassName("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");

                  mysqlDS.setMaxPoolSize(3);

                  mysqlDS.setAllowLocalTransactions(true);

                  mysqlDS.getDriverProperties().put("user", "mydbuser");

                  mysqlDS.getDriverProperties().put("password", "mydbpass");

                  mysqlDS.getDriverProperties().put("url", "jdbc:mysql://localhost:3306/mytestdb");

                  mysqlDS.init();

                 

                  // Setup JPA persistence

                  EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");

                 

                  Environment env = KnowledgeBaseFactory.newEnvironment();

                  env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);

                  env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());

                 

                  // Load and setup the BPM process

                  KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

                  kbuilder.add(ResourceFactory.newClassPathResource(BPMN_RESOURCE), ResourceType.BPMN2);

                 

                  // Do we have any errors ?

                  if (kbuilder.hasErrors()) {

                      if (kbuilder.getErrors().size() > 0) {

                          for (KnowledgeBuilderError error : kbuilder.getErrors()) {

                              System.out.printf("Error building KnowledgeBase: %s\n", error.getMessage());

                          }

                      }

                      throw new RuntimeException("Error building KnowledgeBase");

                  }

                 

                  KnowledgeBase kbase = kbuilder.newKnowledgeBase();

                 

                  StatefulKnowledgeSession ksession = null;

                  if (sessionId > 0) {

                      ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(sessionId, kbase, null, env);

                     

                      JPAWorkingMemoryDbLogger logger = new JPAWorkingMemoryDbLogger(ksession);

                     

                      // Register the custom work item handler

                      ksession.getWorkItemManager().registerWorkItemHandler(WORK_ITEM_NAME, new CustomWorkItemHandler());

                     

                      ProcessInstance processInstance = ksession.getProcessInstance(processId);

                     

                      // Did the process instance complete successfully ?

                      if (processInstance.getState() == ProcessInstance.STATE_COMPLETED) {

                          System.out.printf("\n-----> Restarted business process [%s] successfully completed\n", processInstance.getProcessId());

                      }

                     

                      logger.dispose();

                  }

                  else {

                      ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);

                     

                      JPAWorkingMemoryDbLogger logger = new JPAWorkingMemoryDbLogger(ksession);

                     

                      // Register the custom work item handler

                      ksession.getWorkItemManager().registerWorkItemHandler(WORK_ITEM_NAME, new CustomWorkItemHandler());

                     

                      System.out.printf("\n-----> Session ID: %d\n", ksession.getId());

                     

                      // Create the process instance

                      ProcessInstance processInstance = ksession.createProcessInstance(BPM_PROCESS, null);

                     

                      System.out.printf("\n-----> Starting new Business process %s <ID:%d>\n", processInstance.getProcessId(), processInstance.getId());

                     

                      // Start the BPM process

                      ksession.startProcessInstance(processInstance.getId());

                     

                      // Did the process instance complete successfully ?

                      if (processInstance.getState() == ProcessInstance.STATE_COMPLETED) {

                          System.out.printf("\n-----> Business process %s <ID:%d> successfully completed\n", processInstance.getProcessId(), processInstance.getId());

                      }

                     

                      logger.dispose();

                  }

              }

              catch (Exception ex) {

                  ex.printStackTrace(System.err);

                  System.exit(1);

              }

             

              System.exit(0);

          }

      }

       

      And here is the persistence.xml:

       

      <persistence version="1.0"

                   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence

                                       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd

                                       http://java.sun.com/xml/ns/persistence/orm

                                       http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"

                   xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"

                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                   xmlns="http://java.sun.com/xml/ns/persistence">

       

          <persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">

              <provider>org.hibernate.ejb.HibernatePersistence</provider>

                    

              <jta-data-source>jdbc/MySQL-DS</jta-data-source>

             

              <mapping-file>META-INF/JBPMorm.xml</mapping-file>

              <mapping-file>META-INF/ProcessInstanceInfo.hbm.xml</mapping-file>

             

              <!-- Process Related -->

             

              <class>org.drools.persistence.info.SessionInfo</class>

              <class>org.drools.persistence.info.WorkItemInfo</class>

       

              <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>

                 

              <class>org.jbpm.process.audit.ProcessInstanceLog</class>

              <class>org.jbpm.process.audit.NodeInstanceLog</class>

              <class>org.jbpm.process.audit.VariableInstanceLog</class>

       

              <properties>

                  <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />

                  <property name="hibernate.connection.autocommit" value="false" />

                  <property name="hibernate.max_fetch_depth" value="3"/>

                  <property name="hibernate.hbm2ddl.auto" value="update" />

                  <property name="hibernate.show_sql" value="true" />   

                  <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />

              </properties>       

            </persistence-unit>

         

      </persistence>

       

      Any help appreciated.

        • 1. Re: Work Item not persisted
          swaminathan.bhaskar

          Here is the debug output ... I do see the insert into WorkItemInfo but nothing in the database table while I see a record for ProcessInstanceInfo and SessionInfo

          Any thoughts ?

           

           

          -----> Session ID: 2

           

          Hibernate: insert into ProcessInstanceInfo (OPTLOCK, processId, startDate, lastReadDate, lastModificationDate, state,

          processInstanceByteArray) values (?, ?, ?, ?, ?, ?, ?)

          Hibernate: update SessionInfo set lastModificationDate=?, rulesByteArray=?, startDate=?, OPTLOCK=? where id=? and OPTLOCK=?

          Hibernate: update ProcessInstanceInfo set OPTLOCK=?, processId=?, startDate=?, lastReadDate=?, lastModificationDate=?,

          state=?, processInstanceByteArray=? where InstanceId=? and OPTLOCK=?

           

          -----> Starting new Business process com.bac.jbpm5Samples.sample07 <ID:2>

           

          Hibernate: select processins0_.InstanceId as InstanceId0_0_, processins0_.OPTLOCK as OPTLOCK0_0_, processins0_.processId

          as processId0_0_, processins0_.startDate as startDate0_0_, processins0_.lastReadDate as lastRead5_0_0_,

          processins0_.lastModificationDate as lastModi6_0_0_, processins0_.state as state0_0_, processins0_.processInstanceByteArray

          as processI8_0_0_ from ProcessInstanceInfo processins0_ where processins0_.InstanceId=?

          Hibernate: insert into ProcessInstanceLog (end_date, processId, processInstanceId, start_date) values (?, ?, ?, ?)

          Hibernate: insert into NodeInstanceLog (log_date, nodeId, nodeInstanceId, nodeName, processId, processInstanceId, type) values (?, ?, ?, ?, ?, ?, ?)

          Hibernate: insert into NodeInstanceLog (log_date, nodeId, nodeInstanceId, nodeName, processId, processInstanceId, type) values (?, ?, ?, ?, ?, ?, ?)

          Hibernate: insert into NodeInstanceLog (log_date, nodeId, nodeInstanceId, nodeName, processId, processInstanceId, type) values (?, ?, ?, ?, ?, ?, ?)

          Hibernate: insert into WorkItemInfo (creationDate, name, processInstanceId, state, OPTLOCK, workItemByteArray) values (?, ?, ?, ?, ?, ?)

           

          -----> Waiting in custom work item custom_work_item <ID:2> for 60 secs

          • 2. Re: Work Item not persisted
            swaminathan.bhaskar

            Finally works ... Made some code adjustments to launch a thread from the CustomWorkItemHandler and pass the KnowledgeSession as follows:

             

            import org.drools.runtime.process.*;

             

            public class CustomWorkItemTask implements Runnable {

                private WorkItem item;

                private WorkItemManager manager;

               

                public CustomWorkItemTask(WorkItem item, WorkItemManager manager) {

                    this.item = item;

                    this.manager = manager;

                }

               

                @Override

                public void run() {

                    System.out.printf("\n-----> Waiting in custom work item %s <ID:%d> for 60 secs\n", item.getName(), item.getId());

                   

                    // Artificial wait

                    try {

                        Thread.sleep(60000);

                    }

                    catch (Exception ex) {

                    }

                   

                    System.out.printf("\n-----> Completing custom work item %s <ID:%d>\n", item.getName(), item.getId());

                   

                       manager.completeWorkItem(item.getId(), null);

                }

            }

             

            // -------------------------------------------------------------

             

            import org.drools.runtime.*;

            import org.drools.runtime.process.*;

             

            public class CustomWorkItemHandler implements WorkItemHandler {

                private KnowledgeRuntime ksession;

               

                public CustomWorkItemHandler(KnowledgeRuntime session) {

                    this.ksession = session;

                }

               

                @Override

                public void executeWorkItem(WorkItem item, WorkItemManager manager) {

                    // NOTE: Cannot use the WorkItemManager passed into the method - It will throw the following exception:

                    //       javax.persistence.TransactionRequiredException: No active JTA transaction on joinTransaction call

                   

                    CustomWorkItemTask task = new CustomWorkItemTask(item, ksession.getWorkItemManager());

                   

                    new Thread(task).start();

                }

               

                @Override

                public void abortWorkItem(WorkItem item, WorkItemManager manager) {

                }

            }

             

            Hope this is helpful for someone

            • 3. Re: Work Item not persisted
              loaone

              Hello

               

               

              Does this help check the database which user has logged in??

               

               

              Thanx