The primary difference between BMP and CMP is that, under BMP, developers must write their own datastore access and persistence routines, and respond appropriately to life cycle related calls and callbacks. The bean must provide a public, no-arg constructor for instance creation (invoked by the container).
The bean implements the following methods (for information on the sequence of events, see The Entity Bean Life Cycle):
-
public void setEntityContext(EntityContext ec) — The container normally invokes this method exactly once, just after instantiation, to pass the EntityContext. If the bean will use any EntityContext methods, this is the time to obtain the EntityContext and save the reference in an instance variable. In addition, it is a good time to get any resources that will be used for the bean's lifetime. Be aware that the bean has no object identity at this point and is about to be placed into the pool.
-
public void unsetEntityContext() — This method is also normally invoked exactly once, just before the bean is terminated and sent into the Does Not Exist state. There is no object identity available during this method. This is the proper time to release any resources obtained and to perform any final cleanup.
-
public PrimaryKeyClass ejbCreate(...) — This method is invoked sometime after the client calls a home interface create() method with the same arguments. Notice that the ejbCreate() method returns the primary key, while the container-implemented create() method returns a component instance.
The ejbCreate() method normally validates any arguments, then the developer-written code inserts a row into a database (or performs other datastore create operations), and initializes the corresponding instance variables. In particular, the instance variable or variables representing the primary key must be set at this time.
It is possible to write a bean without an ejbCreate() method, when the class deals only with existing data. In this case, there must be no create() methods exposed on the home interface.
javax.ejb.CreateException and javax.ejb.DuplicateKeyException are standard, API-provided application exceptions that the method may throw.
-
public void ejbPostCreate(...) — There must be a matching ejbPostCreate() method for each ejbCreate() method. The container calls this method after the ejbCreate() invocation so that the bean can perform any necessary post-creation operations. The entity object identity is now available.
The method may throw the javax.ejb.CreateException standard, API-provided application exception.
-
public <primary key type or Collection> ejbFind<METHOD>(...) — These methods are invoked when the client calls a findXXX() method with matching arguments. An instance is selected from the pool, then returned to the pool upon method completion; therefore, any resources obtained during the method should be released. The developer-written code performs datastore search operations in these methods. The finder methods return a single primary key or a Collection of primary keys, depending on whether the argument is expected to return information about a unique entity or multiple entities. For a finder method that returns a Collection, an empty Collection should be returned if no data matching the input arguments is found.
javax.ejb.ObjectNotFoundException may be thrown for a finder that should return a unique value. javax.ejb.FinderException may be thrown by any finder method that encounters an unexpected error.
-
public void ejbLoad() — The container invokes this method when it determines that instance variables representing persistent data must be synchronized with the datastore. This method may be called at any time. The EntityContext methods are available at this time. The developer-written code accesses data in a row from a database (or performs other datastore retrieval operations) in this method.
-
public void ejbStore() — The container invokes this method when it determines that the datastore must be synchronized with the bean instance variables that represent persistent data. This method may be called at any time. The developer-written code updates data in a database row (or performs other datastore update operations) in this method. The developer can rely on instance data to be current during this method call.
-
public void ejbRemove() — This method is invoked sometime after the client calls a remove() method. The EntityContext methods are available at this time. The developer-written code deletes a row from a database (or performs other datastore removal operations) in this method. On completion, the instance leaves the Ready state and is moved to the pool. Because of the transition, the bean state should be the same as it would be after an ejbPassivate() call. A simple way to ensure this result is to call ejbPassivate() after the deletion is performed (the container does not invoke ejbPassivate() after ejbRemove()).
The method may throw javax.ejb.RemoveException if an unexpected error occurs.
-
public void ejbActivate() — The container invokes this method when assigning an object identity and moving the instance from the Pooled state to the Ready state. This is a good time to acquire (or reacquire) any resources needed for the specific identity instance. Persistent data should not be accessed from this method; the container will call ejbLoad() to obtain persisted data.
ejbActivate() will be called for a previously passivated bean. The container will also transition a bean instance from the pool using this method to service an existing entity, which may not have gone through the create() method during the current program run. Therefore, to determine the identity of the data it represents, the bean must call getPrimaryKey() on its EntityContext and set the instance variables representing the primary key. Other EntityContext methods may be called as well. The information associated with the EntityContext will be valid until either ejbPassivate() or ejbRemove() is called.
-
public void ejbPassivate() — The container calls this method when it decides to transition the instance back to the pool. This could happen at any time. Any identity-specific resources should be released in this method. The EntityContext methods are available at this time. Persistent data should not be written in this method; the container will call ejbStore() to persist data.
Because a bean instance can not be certain of the data it represents in the ejbActivate() method until it invokes getPrimaryKey(), and because the instance variables representing the rest of the entity data will be reset on the ensuing ejbLoad() call, it makes sense to set those variables to null here, so they will be eligible for garbage collection. Note that, although the ejbRemove() method transitions an instance to the pool on completion, ejbPassivate() is not called.
-
public type ejbHome<METHOD>(...) — The important thing to understand about home business methods is that there is no specific object identity during method operations. An instance is selected from the pool and, on method completion, returned to the pool. As with ejbRemove(), then, the method should clean up after itself before being returned to the pool. There is no real difference between home methods written for BMP and those written for CMP.