3 Replies Latest reply on Mar 18, 2010 12:00 PM by klawandronic

    Where to implement database work?

      Hi,

       

      I have JBPM 4.3 installed as a service on jboss 5.1.0.GA.

       

      I'm using it from a JSF-EJB3 application through a SLSB layer. So, for example, to start a process, I'm invoking a start method on a SLSB to take advantage of the CMT for any additional work on the application's database.

       

      In the user guide I saw that the recommended way to work with state machine is through event listeners.

       

      What I want to do is: when I start the process I want to save some changes to the application's database(not JBPM's database) by using an event listener on the START event.

       

      My problem is now: how am I supposed to do that if the event listener is not an container managed bean? I cannot inject any session bean in it nor the persistence context. The JBPM engine instanciates event listeners out of the EJB container's scope so out of the EJB scope.

       

      How can I make changes to my database in an JBPM EventListener?

       

      Or, otherwise: how can I propagate the event up to the EJB level so I can then modify the database?

       

      What for are these event listeners intended?

       

      Regards,

      Viorel

        • 1. Re: Where to implement database work?

          OK! Let me put it a little different.

           

          JBPM allows the programmer to run custom code in certain places of a process, as described in the user guide, under the user code paragraph:

           

          Various elements in the jPDL process language refer to a an     object on which an interface method will be invoked.  This section     describes the common attributes and elements for the instantiation and     configuration of such user code objects.


          - custom

          - event-listener

          - assignment-handler in task

          - handler in decision

          - condition in transition

           

          I want this code to perform work on my database, preferably in a transaction.

           

          I followed some guidelines and ended up having a very decoupled but 'not very useful?' architecture:

           

          - JBPM deployed as a service with JTA configured XA on it's Oracle jbpm database

          - business logic code inside a JBoss EJB container working XA on it's Oracle mydb database

          - the EJB layer is starting and signaling JBPM processes sucessfuly right out of the box. GREAT!!!

           

          But now I reached a point where I believe that the custom JBPM user code should actually use data found in mydb database(and/or other business logic code) to be able to perform REAL MAGIC. Otherwise I will have to hard-code business logic stuff in the JBPM custom code and JBPM execution information in the EJB layer; it is obvious that this scenario is to be avoided.

           

          One way to avoid JBPM custom code to interact with the database is to store all info in the process instance variables when starting it. This could be enough if my custom code doesn't need to do database updates - and, normaly, it shouldn't. But take the following scenarion:

           

          - I have a state machine and I start it from the EJB layer

          - then, the recommended way to react on state change(according to common sense and also the user guide) is by using an event listener. GREAT!

          - now the EJB layer needs to signal the process instance to continue to the next state, but my EJB doesn't know what state(the execution id) the process is in now(because I don't want to hard-code the states of the process in the EJB layer) since no one notified it(because my listener is not in the EJB container's scope, thus it cannot signal any EJB), nor find any useful information in the databse(since the listener doesn't have access to mydb) - as I think of it, one way to fix this is to use the listener to store the current execution id inside a process variable(but what if the EJB layer needs to react to the state change imediately or what if there are multiple concurrent executions in the process?)

           

          I know that I may be looking at things in a wrong way, but I wasn't able to find any best practices related to this 'limitation'.

           

          I saw that there is a way to call an EJB layer method from JBPM by using the <java> tag and looking up the bean in JNDI, but I'm not sure this applies to all cases. How can I 'trick' a state machine to notify the EJB layer whenever the state the process is in changes?

           

          Regards,

          Viorel

          • 2. Re: Where to implement database work?
            swiderski.maciej

             

            I saw that there is a way to call an EJB layer method from JBPM by using the <java> tag and looking up the bean in JNDI, but I'm not sure this applies to all cases. How can I 'trick' a state machine to notify the EJB layer whenever the state the process is in changes?

            Try to call your EJB from event listener, it's a java class so you probably can do pretty much the same as from <java> tag.

             

            /Maciej

            • 3. Re: Where to implement database work?

              Thanks Maciej.

               

              I found my way in the end. I'm just looking up the bean in JNDI.

               

              Anyway, I wrote a tutorial on the work I've done so far, see http://community.jboss.org/thread/149637?tstart=0

               

              Regards,

              Viorel