3 Replies Latest reply on Sep 7, 2014 7:57 AM by James Yu

    strange behaviour after enable session persistence

    James Yu Newbie

      Hi all,

       

      I have an example that extends JbpmJUnitBaseTestCase to create Kiesession, let's name this example ExA.

      In ExA, the process will be waiting for external event to continue and complete.

      2014-09-06_003722.png

      So I do startProcess(), signalEvent(), and getProcessInstances() in 3 different methods.

      After startProcess(), the process is waiting for external signal and the state is active (1).

      Then getProcessInstances() confirms that there is 1 undergoing process.

      Finally, signalEvent() triggers the process to continue and its state becomes complete (2).

       

      In ExA, I use the following code snippet to get KieSession to work with:

              manager = createRuntimeManager(bpmfiles);

              engine = getRuntimeEngine(null);

              ksession = engine.getKieSession();

       

      Then I decide to take persistence approach and not to extend JbpmJUnitBaseTestCase no more to run the example, let's call it ExB.

      In ExB, I use the following code snippet to get KieSession:

              ds = new PoolingDataSource();

              ds.setUniqueName("jdbc/testDS");

              ds.setClassName("bitronix.tm.resource.jdbc.lrc.LrcXADataSource");

              ds.setAllowLocalTransactions(true);

              ds.setMaxPoolSize(3);

              ds.getDriverProperties().put("driverClassName", "com.mysql.jdbc.Driver");

              ds.getDriverProperties().put("Url", "jdbc:mysql://localhost:3306/jbpm");

              ds.getDriverProperties().put("password", "jbpm");

              ds.getDriverProperties().put("user", "jbpm");

              ds.init();

              KieServices kservices = KieServices.Factory.get();

              KieStoreServices kstore = kservices.getStoreServices();

              //Create an environment variable with all the database configuration content

              Environment environment = kservices.newEnvironment();

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

              TransactionManager tm = TransactionManagerServices.getTransactionManager();

              environment.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);

              environment.set(EnvironmentName.TRANSACTION_MANAGER, tm);

              //KieSession configuration object to configure special components

              KieSessionConfiguration ksconf = kservices.newKieSessionConfiguration();

              //KieBase we will use to create and restore the runtime from the database

              KieBase kbase = kservices.getKieClasspathContainer().getKieBase();

              //Invocation to create a new persistent session

              ksession = kstore.newKieSession(kbase, ksconf, environment);

      After startProcess(), the process is waiting for external signal and the state is active (1), as expected.

      However processinstancelog table is empty and getProcessInstances() returns null --> this is stange!

      So I skip getProcessInstances() and run again.

      Finally, signalEvent() triggers the process to continue, but its state stays in active (1) --> this is strange.

       

      I attach PTest.java and BPMService.java for your reference.

      PTest.java is the test code I run, and BPMService.java is the actual code to deal with the process.

       

      I need your advise to sort out this problem, thank you.

        • 1. Re: strange behaviour after enable session persistence
          James Yu Newbie

          One quick update.

           

          I just found that I forget to add following line:

              ksession.addEventListener(AuditLoggerFactory.newJPAInstance(environment));

          2014-09-06_070526.png

          after adding the line, process instance is written into processinstancelog:

          2014-09-06_070253.png

          However, the getProcesses() still returns null, and signalEvent() still fails due to there is not process instance to be signaled.

          Following is the calling patterns I tried and the results I got.

           

          Try 1 (call startProcess() then signalProcess() in same run / session):

          2014-09-06_071315.png

          the first red block indicates the process state is active (1), the second red block indicates the process is in active (1), but the state should actually be complete (2)

          because the processinstancelog table says so

          2014-09-06_071418.png

           

          Try 2 (call startProcess() and getProcesses() in same run / session):

          2014-09-06_071758.png

          After invoking testProcess(), a new process instances was created and in active state.

          Somehow getProcesses() is unable to get undergoing processes from database, and this is indicated by the exception.

          In fact, processinstancelog did have the record.

          2014-09-06_072453.png

           

          Try 3 (we call testProcess() and signalProcess() in different runs/sessions):

          2014-09-06_072639.png

          2014-09-06_072740.png

          2014-09-06_072920.png

          2014-09-06_072933.png

          This time, process instance is persist into database all right, but we are unable to signal it to continue.

          The weird thing is that after the exception on signalProcess() / signalEvent(), the persisted data got removed from database.

           

          Any advise is appreciated.

          • 2. Re: Re: strange behaviour after enable session persistence
            James Yu Newbie

            Another update:

             

            I tried to do

            KieSession ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(sessionId, kbase, ksconf, environment);

            and

            KieSession ksession = kstore.loadKieSession(sessionId, kbase, ksconf, environment);

            where sessionId = 1

             

            But none of them works, both of the lines return:

            Exception in thread "main" java.lang.IllegalStateException: java.lang.reflect.InvocationTargetException

                at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.buildCommandService(KnowledgeStoreServiceImpl.java:137)

                at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.loadKieSession(KnowledgeStoreServiceImpl.java:90)

                at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.loadKieSession(KnowledgeStoreServiceImpl.java:39)

                at org.kie.internal.persistence.jpa.JPAKnowledgeService.loadStatefulKnowledgeSession(JPAKnowledgeService.java:130)

                at com.fet.sdp.poc.bpm.BPMService.signalProcess(BPMService.java:131)

                at com.fet.sdp.poc.bpm.PTest.main(PTest.java:37)

            Caused by: java.lang.reflect.InvocationTargetException

                at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

                at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:44)

                at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

                at java.lang.reflect.Constructor.newInstance(Constructor.java:516)

                at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.buildCommandService(KnowledgeStoreServiceImpl.java:122)

                ... 5 more

            Caused by: org.drools.persistence.SessionNotFoundException: Could not find session data for id 1

                at org.drools.persistence.SingleSessionCommandService.initExistingKnowledgeSession(SingleSessionCommandService.java:217)

                at org.drools.persistence.SingleSessionCommandService.<init>(SingleSessionCommandService.java:172)

                ... 10 more

            • 3. Re: Re: Re: strange behaviour after enable session persistence
              James Yu Newbie

              After changing a line in persistence.xml, the session can now be loaded from database.

              However, the process stays in active state even when it reaches the end node.

              How do I load persisted session from database and make it complete ?

               

              The line I changed is:

              <property name="hibernate.hbm2ddl.auto" value="create-drop" />

              and I changed it to:

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