3 Replies Latest reply on Sep 21, 2007 11:36 AM by sonicfab

    Timer problem

    sonicfab

      I am testing a very simple process containing only one node, in which a basic timer is declared. The process is called by the doGet method of a basic servlet :

      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      
       // config
       JbpmConfiguration jbpmConfiguration = (JbpmConfiguration) SpringHelper.getBean(SpringBeans.JBPM_CONFIGURATION);
      
       JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
      
      
       ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
       "<process-definition name=\"toto\" >"+
       "<start-state name=\"start'\">"+
       "<transition name=\"\" to=\"TimerNode\"></transition>"+
       "</start-state>"+
       "<node name=\"TimerNode\"> "+
       "<timer name=\"Timer\" "+
       "duedate=\"1 business minute\" >"+
       "</timer>"+
       "<transition name=\"\" to=\"end1\"></transition>"+
       "</node>"+
       "<end-state name=\"end1\"></end-state>"+
       "</process-definition>"
       );
      
       ProcessInstance instance = new ProcessInstance(processDefinition);
       jbpmContext.save(instance);
      
       instance.signal();
      
       }
      


      The process is instantiated correctly, but I get Hibernate errors when the the signal() method is called :

      10:17:20,117 INFO [STDOUT] 10:17:20,117 ERROR [[ServletTestJbpm]] Servlet.service() for servlet ServletTestJbpm threw exception
      org.jbpm.JbpmException: couldn't cancel timers 'Timer' for 'Token(/)'
       at org.jbpm.db.JobSession.cancelTimersByName(JobSession.java:178)
       at org.jbpm.scheduler.db.DbSchedulerService.deleteTimersByName(DbSchedulerService.java:47)
       at org.jbpm.scheduler.def.CancelTimerAction.execute(CancelTimerAction.java:46)
       at org.jbpm.graph.def.GraphElement.executeAction(GraphElement.java:255)
       at org.jbpm.graph.def.GraphElement.executeActions(GraphElement.java:220)
       at org.jbpm.graph.def.GraphElement.fireAndPropagateEvent(GraphElement.java:190)
       at org.jbpm.graph.def.GraphElement.fireEvent(GraphElement.java:174)
       at org.jbpm.graph.def.Node.leave(Node.java:381)
       at org.jbpm.graph.def.Node.leave(Node.java:357)
       at org.jbpm.graph.def.Node.execute(Node.java:349)
       at org.jbpm.graph.def.Node.enter(Node.java:318)
       at org.jbpm.graph.def.Transition.take(Transition.java:151)
       at org.jbpm.graph.def.Node.leave(Node.java:393)
       at org.jbpm.graph.node.StartState.leave(StartState.java:70)
       at org.jbpm.graph.exe.Token.signal(Token.java:194)
       at org.jbpm.graph.exe.Token.signal(Token.java:139)
       at org.jbpm.graph.exe.ProcessInstance.signal(ProcessInstance.java:270)
       at com.bt.intfwk.testjbpm.ServletTestJbpm.doGet(ServletTestJbpm.java:66)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
       at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
       at java.lang.Thread.run(Thread.java:595)
      Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.jbpm.graph.exe.
      ProcessInstance
       at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:219)
       at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397)
       at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:242)
       at org.hibernate.type.TypeFactory.findDirty(TypeFactory.java:597)
       at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3123)
       at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:472)
       at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:197)
       at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:120)
       at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
       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:969)
       at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1114)
       at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
       at org.jbpm.db.JobSession.cancelTimersByName(JobSession.java:166)
       ... 38 more
      



      Help would be greatly appreciated.

        • 1. Re: Timer problem
          kukeltje

          can you make a unit test for this, so I can easily try to reproduce

          • 2. Re: Timer problem
            sonicfab

            It's really simple. All the timer is supposed to do is wait for one minute.
            I just deploy a servlet so that I can use my browser to signal the process instance. You have the servlet's doGet method code above. Nothing else is needed, because it encapsulates the process definition in XML.

            What I can't understand is why I get this message :

            couldn't cancel timers 'Timer' for 'Token(/)'
            when I call processInstance.signal().
            Why would jBPM be trying to cancel a timer that isn't even started ??!

            • 3. Re: Timer problem
              sonicfab

              PROBLEM SOLVED :

              Apparently jBPM cannot use a timer when the corresponding process definition has only been instantiated in memory from an XML definition but has not been persisted (at least in the Hibernate L1 cache if not in the DB).

              When I add this call after instantiating the process definition, I don't get the Hibernate transient exception anymore :

              jbpmContext.deployProcessDefinition(processDefinition);