[jboss-user] [JBoss Seam] - Re: Seam jBPM: use annotation or pages.xml to get next task?

bsmithjj do-not-reply at jboss.com
Tue Mar 20 16:11:42 EDT 2007


"gavin.king at jboss.com" wrote : anonymous wrote : No, it's not a Seam component (no @Name(...)) annotation - does that work? I mean if I put @Name on my custom ActionHandlers, DecisionHandlers, will Seam inject resources into them on invokation of the execute(ExecutionContext executionContext) methods?
  | 
  | No, of course not, Seam doesn't know anything about them.
  | 
  | Why don't you just make it a seam component, and call it via the EL, instead of going behind Seam's back? It should be easy to do that, right? Just add an annotation and don't bother implementing the interface anymore...

I'm a bit lost on which class you're saying should be a seam component in your last paragraph.  It sounds like you're saying I can't make an ActionHandler into a Seam component and then you're saying I should make it a Seam component...

 Let me give a brief specific example of what I am trying to do and you can tell me what's wrong with it:

Here I have a state in my process definition:

  |   <state name="Provision Response">
  |     <event type="node-enter">
  |       <!-- on entry, fire the auto provision action -->
  |       <action class="com.evergreen.accesscontrol.jbpmaction.AutoProvisionAction"/>
  |     </event>
  |     <transition name="ProvisionSuccess" to="end approval request"></transition>
  |     <transition name="ProvisionFailure" to="end approval request"></transition>
  |   </state>
  | 

And here is the AutoProvisionAction:


  | public class AutoProvisionAction implements ActionHandler {
  | 
  |     private Log log = LogFactory.getLog(AutoProvisionAction.class);
  | 
  |     public void execute(ExecutionContext executionContext) throws Exception {
  |         final EntityManager em = (EntityManager) Component.getInstance("accessControlDatabase");
  |         long accessRequestId = (Long) executionContext.getVariable("accessRequestId");
  | 
  |         AccessRequest accessRequest = null;
  |         User user = null;
  | 
  |         try {
  |             accessRequest = (AccessRequest) em.createQuery(
  |                 "from AccessRequest a fetch all properties where a.id=:id"
  |             ).setParameter("id", accessRequestId)
  |                 .getSingleResult();
  |             EntitlementStorageType entStorageType = accessRequest.getApplication().getEntitlementStorageType();
  |             if (accessRequest.getApplication().getEntitlementStorageType() != null) {
  |                 log.info("EntitlementStorageType=" + accessRequest.getApplication().getEntitlementStorageType().getName());
  |             }
  | 
  |             if (AccessRequestType.Change == accessRequest.getRequestType()) {
  |                 try {
  |                     user = (User) em.createQuery
  |                         ("from User u where u.application.id = :appId and userid = :userid")
  |                         .setParameter("appId", accessRequest.getApplication().getId())
  |                         .setParameter("userid", accessRequest.getUserId())
  |                         .setHint("org.hibernate.readOnly", Boolean.TRUE)
  |                         .getSingleResult();
  |                 } catch (NoResultException e) {
  |                     log.error(
  |                         "Can't find User (userid=" + accessRequest.getUserId() +
  |                             ") for AccessRequest.id=" + accessRequestId
  |                             + ".  Task should be completed in an error state..."
  |                     );
  |                     log.error("automatic provisioning will not be attempted");
  |                     return;
  |                 }
  | 
  |             }
  |             AccessOperationDocument accessOperationDocument = EvergreenSecurityAdaptorUtility
  |                 .convertAccessRequestToAccessOperationDocument(
  |                     accessRequest, String.valueOf(executionContext.getProcessInstance().getId()), user
  |                 );
  | 
  |             if (accessOperationDocument == null) {
  |                 log.error("There was a problem creating the AccessOperationDocument for Evergreen-Security Auto-Provisioning.");
  |                 log.error("TODO - close task in an error state when this occurs");
  |                 log.error("automatic provisioning will not be attempted");
  |                 return;
  |             }
  |             JMSSender jmsSender = (JMSSender) Component.getInstance("simpleJmsSender");
  |             jmsSender.sendMessage(accessOperationDocument.xmlText());
  |         } catch (NoResultException e) {
  |             log.error("Can't load AccessRequest for id=" + accessRequestId + ".  Task should be completed in an error state...");
  |         }
  |     }
  | 
  | }
  | 

notice I need to acquire some resources that typically Seam would inject into a session bean - anywhere there is Component.getInstance(...) I use @In or @EJB in my Seam components.  I was having so many NO_TRANSACTION issues when I tried to keep this logic in a session bean, I struggled with this for a while and ultimately I found that by using Component to get the desired resources and implementing the logic in place that you see here (which formerly was in a session bean), I was able to do what I needed without running into transactional issues.  Basically, If I do all the work associated with an ActionHandler in place, I do not run into transaction problems, the moment that I cross the EJB-method invokation line, transaction issues arise.

It would be ideal if jBPM Handlers (ActionHandler, DecisionHandler, etc.) could be first class Seam components and have Seam intercept execute() invokations and @Inject/@Outject resources.

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4029986#4029986

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4029986



More information about the jboss-user mailing list