A message-driven bean is a server-side message consumer that has, according to the EJB specification [3] the following characteristics:
The EJB 2.0 specification supported only JMS message-driven beans. The EJB 2.1 specification extends the message-driven bean contracts to support other messaging types in addition to JMS. Transaction demarcation for message-driven beans is similar to the session beans as shown above. Again, both BMT and CMT are possible. In the case of CMT, only the Required and NotSupported transaction declarations make sense and are allowed. Transaction management in the context of JDO for persistence operations is identical to what has been discussed earlier for session beans: Obtaining a PersistenceManager inside a CMT bean onMessage() method ensures that it is always correctly associated and enlisted in the respective J2EE transaction. 9.3.1 Example codeThe following code snippet shows how a message-driven bean might look: public class OrderBooksBean implements MessageDrivenBean, MessageListener { private MessageDrivenContext ejbMsgCtx; private PersistenceManagerFactory jdoPMF; public void ejbCreate() { } public void setMessageDrivenContext( MessageDrivenContext messageDrivenContext) throws EJBException { ejbMsgCtx = messageDrivenContext; try { String jndiName = "java:comp/env/jdo/PMF"; Context jndiInitCtx = new InitialContext(); Object o = jndiInitCtx.lookup(jndiName); jdoPMF = (PersistenceManagerFactory) PortableRemoteObject.narrow (o, PersistenceManagerFactory.class); } catch (NamingException ex) { throw new EJBException(ex); } } public void ejbRemove() throws EJBException { } /** * Updates orders in persistent books. * Finds a book with the message.bookISBN, and * if its price is lower than message.maxPrice, * then adds a new order for the message.clientNum. **/ public void onMessage(Message message) { PersistenceManager pm = null; try { MapMessage mapMsg = (MapMessage)message; String bookISBN = mapMsg.getString("bookISBN"); double maxPrice = mapMsg.getDouble("maxPrice"); long clientNum = mapMsg.getLong("clientNum"); pm = jdoPMF.getPersistenceManager(); BookID oid = new BookID(bookISBN); Book book = (Book)pm.getObjectById(oid, true); if ( book.getPrice() <= maxPrice ) { pcBook.newOrder(clientNum); } else { // Don't order... reject? } } catch (Exception ex) { ejbMsgCtx.setRollbackOnly(); throw new EJBException(ex); } finally { try { if (pm != null && !pm.isClosed()) pm.close(); } catch (Exception ex) { // Log it } } } } If persistent objects were to be included in messages, e.g., using javax.jms.ObjectMessage , then the points raised earlier in the context of session-bean parameters (serializability or DTO, graph of objects, object ID as String, and so on) would similarly all apply.
|