7 Replies Latest reply on Nov 16, 2010 4:00 AM by LX T

    JBPM 4.3: Is it possible to leave current state on timer listener?

    Nugroho Saputro Newbie

      Hi All,

      Please help me, I am newbie at JBPM 4.x. I have a problem with leaving a state programmatically in timer listener. I always get exception like this:

       

      {code} 12 Apr 2010 11:21:11 ERROR org.jbpm.pvm.internal.cmd.ExecuteJobCmd  - exception while executing 'timer[30|2010-04-12 11:21:11,412|timeout]' org.jbpm.api.JbpmException: execution[Order.22] is not active: inactive-scope      at org.jbpm.pvm.internal.model.ExecutionImpl.checkActive(ExecutionImpl.java:1024)      at org.jbpm.pvm.internal.model.ExecutionImpl.take(ExecutionImpl.java:466)      at org.jbpm.pvm.internal.model.ExecutionImpl.takeDefaultTransition(ExecutionImpl.java:449)      ...

           ... {code}

       

       

      What I would like to do is checking status from database repeatedly every X minutes. When it found certain status e.g. COMPLETED it should go to the next state, otherwise it will repeat until that status is reached.

      Currently I implement it as a state with a repeated timer:

      {code:xml} <state name="Check Order Status">   <on event="timeout">     <timer duedate="10 minutes" repeat="10 minutes"/>     <event-listener expr="#{OrderStatusChecker}"/>   </on>   <transition name="to-status-decision" to="status-decision"/> </state> {code}

       

       

      and on the timer listener:

       

      {code:java} public class OrderStatusChecker implements EventListener {     public void notify(EventListenerExecution event) throws Exception {                // Check status.         String status = ...... get status from Database ...         event.getProcessInstance().setVariable("status", status);                 if (status.equals("COMPLETED")) {             // Leave current state             ActivityExecution execution = (ActivityExecution) event.getParent();             execution.takeDefaultTransition();         }                    } } {code}

       

       

       

      Is it possible to do that in JBPM?  If it's not possible, is there any workaround for my case?

       

      I use JBPM4.3 with spring 2.5.

       

      Thank you.

       

      Regards,

      Nugroho

        • 1. Re: JBPM 4.3: Is it possible to leave current state on timer listener?
          HuiSheng Xu Master

          Hi Nugroho,

            You should use ((ActivityExecution) execution).takeDefaultTransition();  The parent of the current execution is in the inactive-scope state.

          1 of 1 people found this helpful
          • 2. Re: JBPM 4.3: Is it possible to leave current state on timer listener?
            Nugroho Saputro Newbie

            Huisheng Xu wrote:

             

            Hi Nugroho,

              You should use ((ActivityExecution) execution).takeDefaultTransition();  The parent of the current execution is in the inactive-scope state.

            Huisheng, thank you for your suggestion. I tried that but it still does not take to next state.

             

            I got this error if repeat attribute is specified on timer:

             

            {code}

            13 Apr 2010 15:35:50 INFO  org.jbpm.pvm.internal.svc.DefaultCommandService  - exception while executing command org.jbpm.pvm.internal.jobexecutor.GetNextDueDateCmd@d83365 org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [org.jbpm.pvm.internal.model.ExecutionImpl#22]      at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:409)      at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:171)      at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)      at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)      at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)      at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:873)      at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:590)      at org.hibernate.type.EntityType.resolve(EntityType.java:412)      at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)      at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:877)      at org.hibernate.loader.Loader.doQuery(Loader.java:752)      at...

            {code}

             

            if I remove repeat attribute, no exception is thrown, but it's still in the current state (Check Order Status).

            • 3. Re: JBPM 4.3: Is it possible to leave current state on timer listener?
              Maciej Swiderski Master

              Hi,

               

              in my opinion event listeners should not be used to change the flow of the process. It should be treated as additional hooks in the process that are not visible on the process diagram and that's why are perfect for non business related activities such as logging, event submition, etc.

               

              What you could do it so you timer transition, as follows:

               

                  <transition name="timeout" to="escalation">
                    <timer duedate="10 minutes" />
                  </transition>
              

              If you put this in your wait node after 10 minutes (unless it will be signaled) transition will be taken.

               

              In your case you could either check all you need in associated event listener when taking this transition or have a user activity (java, custom) for such a check. Next you move on to decision point to verify what to do, if status is not yet correct go back to wait state to wait another 10 minute or move on with your process.

               

              HTH

              Maciej

              1 of 1 people found this helpful
              • 4. Re: JBPM 4.3: Is it possible to leave current state on timer listener?
                Nugroho Saputro Newbie

                Hi Maciej,

                 

                Thank you for your suggestion.Unfortunately I get another exception when timer on re-check transition is executed  by jobexecutor:

                simple_java.png

                 

                {code}

                 

                23:22:03,041 SEV     | [JobParcel] exception in job block
                org.springframework.dao.DataIntegrityViolationException: could not update:
                [org.jbpm.pvm.internal.model.ExecutionImpl#17]; nested exception is org.hibernate.exception.ConstraintViolationException:
                could not update: [org.jbpm.pvm.internal.model.ExecutionImpl#17]
                at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:636)
                at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:789)
                at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:663)
                at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:732)
                at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
                at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
                at org.jbpm.pvm.internal.tx.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:55)
                at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
                at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
                at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:55)
                at org.jbpm.pvm.internal.jobexecutor.JobParcel.run(JobParcel.java:48)
                        ...
                Caused by: org.hibernate.exception.ConstraintViolationException: could not update: [org.jbpm.pvm.internal.model.ExecutionImpl#17]
                at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
                at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
                at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2453)
                at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335)
                at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635)
                at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
                at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
                        ....
                Caused by: java.sql.SQLException: Violation of unique constraint $: duplicate value(s) for column(s) $: SYS_CT_50 in statement
                [update JBPM4_EXECUTION set DBVERSION_=?, ACTIVITYNAME_=?, PROCDEFID_=?, HASVARS_=?, NAME_=?, KEY_=?, ID_=?,
                STATE_=?, SUSPHISTSTATE_=?, PRIORITY_=?, HISACTINST_=?, PARENT_=?, INSTANCE_=?, SUPEREXEC_=?, SUBPROCINST_=?
                where DBID_=? and DBVERSION_=?]
                at org.hsqldb.jdbc.Util.throwError(Unknown Source)
                at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
                at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2435)
                ... 26 more

                 

                {code}

                 

                 

                Do you have any idea why I get this exception?

                • 5. Re: JBPM 4.3: Is it possible to leave current state on timer listener?
                  Maciej Swiderski Master

                  yeap, I had that as well, there is already open issue for that. Problem is with creating timer in a wait node after going though the loop. The id is the same as for the expired one and both are inside the same transaction.

                   

                  A workaround for this is to make continuation of the activity (Check Order status) as async. Just add to your (assuming it is java) activity following attribute:

                  continue="async" 
                  

                  And that error should go away.

                   

                  Cheers,

                  Maciej

                  • 6. Re: JBPM 4.3: Is it possible to leave current state on timer listener?
                    Nugroho Saputro Newbie

                    Maciej Swiderski wrote:

                     

                    yeap, I had that as well, there is already open issue for that. Problem is with creating timer in a wait node after going though the loop. The id is the same as for the expired one and both are inside the same transaction.

                     

                    A workaround for this is to make continuation of the activity (Check Order status) as async. Just add to your (assuming it is java) activity following attribute:

                    
                    continue=async 
                    
                    

                    And that error should go away.

                     

                    Cheers,

                    Maciej

                     

                    Thank you Maciej. It works.

                    • 7. Re: JBPM 4.3: Is it possible to leave current state on timer listener?
                      LX T Newbie

                      I am trying to get the current activityExecution like in the above example:

                       

                      ActivityExecution execution = (ActivityExecution) event.getParent();

                      but I get null. What can be the problem? Thanks.