G |
Entity Beans |
|
Get |
Get |
Overview |
Session beans are all about functionality, application logic, and application state. Entity beans, on the other hand, represent persistent business entities or data. In a typical project requirements document, session beans would model the tasks or verbs, while entity beans would model the nouns: people, places, and things. Although an entity bean typically represents a row from a database table, the datastore can be any persistence mechanism that the container or developer can manage, including incoming data from other applications (legacy connector applications, for example). Note that for read-only applications, entity beans may be overkill and raise performance issues. For these applications, direct access from the client or, more likely, a session bean, is an alternative worth considering.
The specification mandates that there normally must be a create()
/ejbCreate()
method pair, an ejbPostCreate()
method with matching arguments for each ejbCreate()
method, and always a findByPrimaryKey()
/ejbFindByPrimaryKey()
method pair.
As mentioned earlier, create()
/ejbCreate()
and remove()
/ejbRemove()
have completely different functions with entity beans: create()
creates persistent data, usually meaning the insertion of a row into a database table, and remove()
deletes the persistent data. In this instance, the create()
method will have at least a primary key argument and normally will have several data initialization arguments as well.
The findByPrimaryKey()
method, like the create()
method, returns a component interface and is the means by which a client obtains an entity bean to represent existing data. There may be multiple finder methods based on different values, each of which must return either a component interface or a Collection
of component interfaces. Finder methods are named, again in matching sets, findByXXX()
and ejbFindByXXX()
with appropriate arguments. The ejbFindByPrimaryKey()
method, like the ejbCreate()
method, returns the primary key; other ejbFindXXX()
methods may return a single primary key or a Collection
of primary keys. The container handles the magic of converting from primary key to component interface instance in the create()
method (but see the differences between BMP and CMP in Table EB-1 below).
A primary key is a unique identifier for a bean instance and is a key to the data, usually correlating to the primary key for a row in a table. A primary key must be an Object
; primitives are not allowed. If no existing class can serve as a primary key or if the primary key consists of more than one variable (or column, if you prefer), then a custom class must be written to represent the key, with instance variables acting as composite key components. In order to work with both container-managed and bean-managed persistence, a primary key class must meet these guidelines:
hashCode()
and equals(Object obj)
methods.
In addition to create, finder, and remove methods, an entity bean may expose home methods in its home interface. Home methods provide logic for operations that are not specific to a unique bean instance. This usually means an operation that requires working with more than one instance to obtain the desired result. Some examples include counting U.S. customers with a zip code of 80110; imposing a late charge on all accounts 30 days overdue; or calculating sales totals for a specific region. Home methods may have an arbitrary name in the home interface. In the bean implementation, the corresponding method must match arguments and have a name composed of the prefix ejbHome
plus the name given in the home interface with the initial letter capitalized. For instance, a home interface home method defined as int countCustomers( String country, String postalCode )
would, in the bean implementation, be written as int ejbHomeCountCustomers( String country, String postalCode )
.
Entity beans may be pooled in a manner similar to stateful session beans, but in this case passivation/activation also causes the data to be persisted to and read from the datastore, respectively. All other resources must be released and reacquired, as appropriate.
An entity bean provides shared access to its data, and it is possible that the same data may be modified by multiple clients. In this sort of scenario, it becomes critical that beans can work within the proven methodology of transactions (see What Are Transactions?). The container provides for both bean-managed and container-managed demarcated transactions; the type of transaction management and transactional attributes are declared in the deployment descriptor. Entity beans must use container-managed transactions.
As previously noted, there are two methods of persistence available: bean-managed persistence (BMP), which is implemented by the developer, and container-managed persistence (CMP), which is implemented by the container. Both of these persistence methods are discussed in the following sections and illustrated in the example application. In each case, the container controls the timing of inserts, updates, refreshes/synchronization, and deletes.
While the specifics of BMP and CMP will be covered shortly, Table EB-1 (taken from Chapter 6 of The J2EE Tutorial — see Resources) is a useful quick reference for responsibility and coding differences between the two persistence types.
Difference |
Container-Managed |
Bean-Managed |
---|---|---|
Class definition |
Abstract |
Not abstract |
Database access calls |
Generated by tools |
Coded by developers |
Persistent state |
Represented by virtual persistent fields |
Coded as instance variables |
Access methods for persistent and relationship fields |
Required |
None |
findByPrimaryKey method |
Handled by container |
Coded by developers |
Customized finder methods |
Handled by container, but the developer must define the EJB QL queries |
Coded by developers |
Select methods |
Handled by container |
None |
Return value of ejbCreate |
Should be null |
Must be the primary key |
![]() ![]() ![]() ![]() |