Entity Beans with Bean-Managed Persistence
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
EntityContextmethods, this is the time to obtain the
EntityContextand 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.
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.
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.DuplicateKeyExceptionare 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.
javax.ejb.CreateExceptionstandard, 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
Collectionof 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
Collectionshould be returned if no data matching the input arguments is found.
javax.ejb.ObjectNotFoundExceptionmay be thrown for a finder that should return a unique value.
javax.ejb.FinderExceptionmay 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
EntityContextmethods 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
EntityContextmethods 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
javax.ejb.RemoveExceptionif 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
EntityContextand set the instance variables representing the primary key. Other
EntityContextmethods may be called as well. The information associated with the
EntityContextwill be valid until either
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
EntityContextmethods are available at this time. Persistent data should not be written in this method; the container will call
ejbStore()to persist data.
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
nullhere, 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.