Download (direct link):
Figure 43.1 The index class diagram.
366 Item 43
Ů EJB_Context : javax.ejb.MessageDrivenContext = null
^7 MessageDriven() ^7<<EJBCreateMethod>> ejbCreate() onMessage()
Figure 43.2 The MessageDriven EJB class diagram.
The container creates message-driven beans to handle the receipt of an asynchronous message. Figure 43.2 shows a message-driven EJB called MessageDriven. Notice that there are no interfaces from which client applications can directly invoke the bean. This means that the only access to this bean would be to send a message to the queue that this message-driven bean would handle. When that happens, the container calls the onMessage() method. All of the business logic would be contained within that onMessage() method.
This is clearly problematic for two reasons. First, reinitializing the index on every invocation is completely inconsistent with our purposes (a shared instance). Second, the means of communicating with our EJB is not supposed to be asynchronous. So, clearly this option was not seriously considered, but for the sake of completeness, we had to look at it.
Next, we considered using an entity bean. Thinking about it, we realized that the index could be considered a persistent business object. Figure 43.3 shows the Entity EJB class diagram.
Notice that the EntityHome interface contains the pertinent create() and findByPrimaryKey() methods. The remote interface, Entity, has the search() method within it. Notice that all of the clients would have to try the findByPrima-ryKey() method to see if the index was created, and if not, create it. Once the reference has been grabbed, the client could call the search() method.
The Stateful Stateless Session Bean 367
Remote Entity w Home /"~n EntityHome w
¦^«EJBRemoteMethod» search() <<EJBRemoteMethod>> create() *;j<<EjBFinderMethod>> findByPrimaryKeyO
f;:»EJB_Context : javax.ejb.EntityContext C?EJB_Connection : java.sql.Connection = null C*EJB_Datasource : java.sql.DataSource = null
*;j<<EJBFinderMethod>> ejbFindByPrimaryKeyO <<EJBCreateMethod>> ejbCreate() <<EJBCreateMethod>> ejbPostCreate()
Figure 43.3 The Entity EJB class diagram.
Seems to be a good idea, right? Well, this ignores the fact that entity beans are notoriously slow and it is considered bad practice to interact with them directly, instead of referencing them through session beans (known commonly as the Session Facade pattern). Of course, even if using the Session Facade, this is a classic example of using a sledgehammer to drive a tack—that is, overkill. It could be counterproductive in terms of the additional processing time required to maintain the index in persistence and it could cost more time than re-creating the index on each invocation. After all, the purpose of the entity bean is to ensure that the object survives system failure. Also, if the system fails, then the index can be re-created upon reinitialization of the system. Since we are now persisting this object, we will need to have a methodology to propagate changes to the index so that it does not become a permanently configured instance. This requires additional functionality to handle a case that is not really a requirement for this problem (persistence).
368 Item 43
Furthermore, writing the persistence code for something that does not map very congruently with a database (an object) can be a really big pain. Even if the effort is not as bad as it appears, it is still more than is necessary.
Therefore, we saw some real drawbacks in using the entity bean solution. So we decided to review further ideas, which brought us to session beans.
Stateful Session Bean
The stateful session bean provides an interesting alternative. The stateful session bean maintains state across client invocations but does not have the performance overhead of attempting to maintain persistence to survive system crashes. If the system crashes, then the state is lost and must be reestablished.
Figure 43.4 is the class diagram for the stateful session bean, called Stateful. The diagram shows the remote and home interfaces for the stateful session bean. Notice the create() method and the requisite index object theIndex. Also, the remote interface contains the search() method for searching the index.
However, the purpose of the stateful session bean is to maintain the conversation state between the client and server across invocation, essentially tracking the interaction. As such, this means that there is a separate context for each client conversation. This in turn means that every client would create its own index object at the beginning of interaction. Then the client would invoke the search method, and the interaction would end. This is not a shared instance, as the performance hit from initialization comes with each client.