3 Replies Latest reply on Jan 10, 2006 4:56 PM by Alejandro Guizar

    Persisting jBPM in a stateless session bean

    Johan Hoogenboezem Newbie

      Hi,
      I've managed to set it up so I can retrieve process instances from the database inside a container managed transaction. However, when trying to save changes back to the database, I ran into a problem. It turned out the changes were never saved to the database. I tried to manage the transaction myself, but the container (JBoss 4.0.3SP1) complained, which was not unexpected. Just closing the session should've been sufficient, but didn't have the desired effect.
      Eventually I retrieved the Hibernate session from the JbpmSession and called flush() on it before calling close() on the JbpmSession. This had the desired effect. Looking at the code for JbpmSession, I noticed that in commitTransaction(), the flush() was being called, so it seemed that I was on the right track.
      Maybe it is Hibernate that should flush() when a managed transaction is comitted - or maybe jBPM should do it? Or maybe this should just be documented?
      Any comments?

      Here's an example of how I use jBPM inside a bean:

       public some.data.Object advanceProcess(
       long processInstanceId, Serializable data) {
       Connection conn = null;
       JbpmSession session = null;
       try {
       long start = System.currentTimeMillis();
       conn = getNamingService()
       .lookupDataSource(NamesDirectory.JBPM_DATASOURCE).getConnection();
       session = sessionFactory.openJbpmSession(conn);
       // Now we can query the database for the process definition that we
       // deployed above.
       ProcessInstance processInstance = session.getGraphSession()
       .loadProcessInstance(processInstanceId);
       if (processInstance == null)
       throw new DomainRuntimeException("Unable to load process instance for "
       + processInstanceId);
       processInstance.signal();
      
       // do some more stuff here
      
       session.getGraphSession().saveProcessInstance(processInstance);
       L.info("It took "
       + (System.currentTimeMillis() - start)
       + "ms for the '"
       + processInstance.getProcessDefinition().getName()
       + "' process to reach the '"
       + processInstance.getRootToken().getNode().getName()
       + "' node.");
       return returnData;
       }
       catch (SQLException e) {
       throw new RuntimeException(e);
       }
       finally {
       if (session != null) {
       try {
       session.getSession().flush();
       session.close();
       }
       finally {
       try {
       if (conn != null)
       conn.close();
       }
       catch (SQLException e) {
       throw new RuntimeException(e);
       }
       }
       }
       else {
       try {
       if (conn != null)
       conn.close();
       }
       catch (SQLException e) {
       throw new RuntimeException(e);
       }
       }
       }
       }
      
      


      Regards
      Johan