MessageDriven Beans accepting EJB reference parameters


EJB design: MessageDriven Beans accepting EJB reference parameters

  1. Hi all,

    For the 2nd edition of the "Mastering EJB" book, two of the co-authors (myself and Tyler Jewell) are looking to the community's input on a design issue.

    We have the following beans:

    * A ShoppingCart Stateful Session Bean
    * An OrderProcessing MessageDriven Bean
    * An Order Entity Bean

    The OrderProcessing MDB takes the ShoppingCart as input, and produces an Order, while also checking the user's credit worthiness, sending an email confirmation, and so-on. We use an MDB so that the user can continue to browse the web site when he is ready to Order.

    Our question is.. can an MDB take a Stateful Session Bean reference as input? If not, can handles be used instead? Will the handle work properly from the MDB?
  2. I don't see how you can pass anything other than a javax.jms.Message to the MDB.

    Serializing a reference and storing it inside a Message, expecting to reconstitute it on the other end of the JMS queue, as far as I know will just not work.

    I dont' see any reason why a jms Message can't contain a serialized handle, that gets reconstituted on the other side of the JMS queue, and converted back to a real live ejb reference.

    But I'm not sure what it means to pass around a handle to a stateful session bean. This seems to imply that the "session" is sort of being hijacked by the MDB.

    For this proposed architecture, i would imagine that the shopping cart would have to be modelled as an entity bean, so that it could be shared by the true client and the MDB.

    I have to ask: Is this a serious question from Ed Roman, author of "Mastering EJB"?
  3. Hi Ed,

    Cant getEJBObject on the SessionContext be used to pass the reference for call backs on the Stateful bean.

  4. Please ignore the above comment. just check out the jms specs. only javax.jms.Message allowed as paramater.


  5. Ed,

    You might want to consider the binding issue when the remote reference is deserialized. Most middleware solutions on the market perform local optimizations but most of the time they cannot work when the handle is brought into the container in this manner instead of being bound through an ejb-ref. Along with losing this optimization you also have the possibility of referencing out into another container which I do not think you want in most cases. That extra rpc would negate most of the performance benefits associated with the messaging middleware.

    William Louth
  6. Guys,

    What about making a helper class (some kind of value object for stateful session) for your ShoppingCart stateful and pass reference to that class to MDB and implement all the functionality with order data in another session bean (or beans), that will be looked up already in MDB?

  7. Hi,

    With all due respect, such questions don't really encourage me to buy the book ;)
  8. Tha's why above I had to ask if this was a serious question. No reply either, can't really call this a discussion.
  9. Why not use an ObjectMessage and set the object to EJBObject.getHandle()? You can then use Handle.getEJBObject() inside the MDB.
  10. But what does it mean to pass around a handle/reference to a statefull session bean???

    Who is the client, the real client or the MDB?

    Are there now two sessions? The real client and the MDB?

    What security identity is doing the work?

    Yes it is possible to pass around a handle, but it just doesn't make sense to share a statefull session bean, between a real client and a server side MDB running under some other identity.

    Pass the state/data, not a reference to a statefull session bean, or share the state through an entity bean.
  11. Completely agree. Although your version is somewhat shorter than mine! :-)


  12. _Theoretically_ the session bean interface is an extension of the Remote interface isn't it? In that case, passing it around should simply pass around the remote proxy which implements it and it should work. The sever may well short circuit the remote method semantics if it's all in the same VM, but other than that it makes sense it should work.

    However, that assumes:

    a) It's a remote interface.
    b) The session bean is not being used elsewhere (for instance on the HTTP thread from the web site) since that would violate the threading restrictions of session beans.

    All of this however, is really just about if it is possible. Whether it is a good idea is another matter.

    The contents of the cart are order line items, and it is the line items which are of relevance to the MDB, not the container of those items. Would it not be cleaner to "flush" the order to the MDB? At this point the order is just a value object, not an entity EJB right? Wouldn't see the point in creating the entity bean until the order is placed (how many times do we put things in our cart and then leave the site without doing anything?)

    The user can then check the status of their order by going to the orders page. Logically it's an order at this point, not something in your shopping cart any more.

    So it would go something like this.

    Cart (contains order value objects)
           Message Driven Bean
         (checks credit, if OK..)
           Creates Entity Bean

    Last step is for MDB to send confirmation email.

    For that matter the stateful session bean may be overkill, since you can just as easily store the cart in an HTTPSession, and more and more servers will provide HTTPSession replication across a cluster. But then it probably wouldn't fit the bill as an EJB example would it!