7 Replies Latest reply on Feb 16, 2007 3:53 PM by estaub

    cancelTimersForProcessInstance fails if process is not saved

    kukeltje

      Env:
      - jBPM 3.1.1
      - jdk 1.5.0_06
      - windows xpsp2

      We are (ab)using jbpm (jpdl) for a stp service where we eventually will use jbpm bpel. It is a process witrh custom nodes which do sync or async calls to an ESB (Mule). There are no wait states so this means the processInstance is signalled and right before the signal method gets back the process is in fact ended.

      On calling the ProcessInstance.end(), all timers are being cancelled. This fails

      at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:216)

      at org.hibernate.type.EntityType.getIdentifier(EntityType.java:108)

      at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:221)

      at org.hibernate.type.TypeFactory.findDirty(TypeFactory.java:476)

      at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:2802)

      at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:457)

      at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:180)

      at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:104)

      at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:195)

      at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)

      at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:35)

      at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:878)

      at org.hibernate.impl.SessionImpl.prepareQueries(SessionImpl.java:1071)

      at org.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:1061)

      at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1041)

      at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:89)

      at org.jbpm.db.SchedulerSession.cancelTimersForProcessInstance(SchedulerSession.java:169)

      at org.jbpm.scheduler.db.DbSchedulerService.cancelTimersByProcessInstance(DbSchedulerService.java:55)

      at org.jbpm.graph.exe.ProcessInstance.end(ProcessInstance.java:275)
      ...
      ...

      The cause is that

      public void cancelTimersForProcessInstance(ProcessInstance processInstance) {
       try {
       Query query = session.getNamedQuery("SchedulerSession.deleteTimersForProcessInstance");
       query.setEntity("processInstance", processInstance);
       query.executeUpdate();
      
       } catch (Exception e) {
       log.error(e);
       jbpmSession.handleException();
       throw new JbpmException("couldn't delete timers for process instance '"+processInstance+"'", e);
       }
       }


      fails in the following hibernate query

      <query name="SchedulerSession.deleteTimersForProcessInstance">
       <![CDATA[
       delete from org.jbpm.scheduler.exe.Timer t
       where t.processInstance = :processInstance
       ]]>
       </query>


      Which is 'logical' since the processinstances is not saved yet in any way. So the hibernate exception is valid.

      Introducing a state where we save the process and signal it again to do the real work works, but that is not what we want.

      Any tips/hints?

      btw, to be comlete so David will not answer with the link, here is my custom node:



      package net.vankuijk.jbpm.customNode;
      
      import org.jbpm.graph.def.ActionHandler;
      import org.jbpm.graph.exe.ExecutionContext;
      
      public class MyNode implements ActionHandler {
      
       public void execute(ExecutionContext executionContext) throws Exception {
      
       executionContext.leaveNode();
       }
      
      }


      and my process:

      <?xml version="1.0" encoding="UTF-8"?>
      
      <process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="customNode">
      
       <start-state name="start">
      
       <transition name="node1" to="node1"></transition>
      
       </start-state>
      
       <node name="node1">
      
       <action class="nl.vankuijk.jbpm.customNode.MyNode" </action>
      
       <transition name="to_end" to="end"></transition>
      
       </node>
      
       <end-state name="end"></end-state>
      
      </process-definition>
      
      
      




        • 1. Re: cancelTimersForProcessInstance fails if process is not s
          kukeltje

          ok, still one omission, the error itself got lost in typing the post:

          Root Exception stack trace:

          org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.jbpm.graph.node.EndState

          • 2. Re: cancelTimersForProcessInstance fails if process is not s
            kukeltje

            additional info:

            It also fails if we introduce a real state, save the process instance and close the context. The same hibernate error occurs then on the close statement. Only in the specific state and not in the end state.

            Besides that, the processdefinition is loaded from a file. We do not need persistency and the process works fine if we do not use async nodes. In this case a jbpmContext is not needed. We do however need async nodes and for that to work a jbpmContext seems needed. If we introduce a jBPMContext, every attempt explicitly or implicitly to persist something results in the hibernate error

            • 3. Re: cancelTimersForProcessInstance fails if process is not s
              kukeltje

              seconds after posting the previous message, we found a solution. We created a new jbpm config with out all required services. This works.

              Thanks for such a flexible engine ;-)

              • 4. Re: cancelTimersForProcessInstance fails if process is not s
                koen.aers

                 

                "tom" wrote:
                You're welcome!


                ;-)

                Cheers,
                Koen

                • 5. Re: cancelTimersForProcessInstance fails if process is not s
                  kukeltje

                  He, what's this? Are you in a new role? Did you get promoted to become Toms personal assistent?

                  :-P

                  • 6. Re: cancelTimersForProcessInstance fails if process is not s
                    koen.aers

                    I have this position already for quite some time ;-)

                    But in this case, I merely wrote down what Tom said when I showed him your entry while sitting in our first RH meeting...

                    Cheers,
                    Koen

                    • 7. Re: cancelTimersForProcessInstance fails if process is not s

                      I just ran into exactly the same problem, using the default config.

                      My case was more complicated, but it fails with the "HelloWorld" tutorial definition, i.e.,

                      jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();
                      
                       ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
                       "<process-definition>" +
                       " <start-state>" +
                       " <transition to='s' />" +
                       " </start-state>" +
                       " <state name='s'>" +
                       " <transition to='end' />" +
                       " </state>" +
                       " <end-state name='end' />" +
                       "</process-definition>"
                       );
                      
                       ProcessInstance processInstance =
                       new ProcessInstance(processDefinition);
                       Token token = processInstance.getRootToken();
                       token.signal();
                      
                       jbpmContext.save(processInstance);
                       jbpmContext.close();



                      I guess I'm a little less charitable than Ronald.
                      Isn't this a bug?

                      -Ed Staub