Guidelines: Designing Enterprise JavaBeans (EJBs)
Topics
Introduction
This guideline focuses on designing EJBs. Additional guidance on EJBs, such
as how to identify and model them, is provided by Guidelines:
EJBs.
Specific guidance on designing specific types of EJBs is provided in the following
guidelines:
Local and remote interfaces are described in Concepts:
J2EE Overview: Enterprise JavaBeans.
Local interfaces are more efficient than remote interfaces. Local interfaces
should be provided if there are specific clients which are always local to the
EJB.
More specific guidance on this topic is provided in the guidelines for the
specific types of EJBs.
Parameter Passing
Performance can be dramatically affected by the number of remote calls and
the amount of data transferred on each call. This can be addressed by providing
specific calls that return all the data that the remote client requires. For
example, a session bean, acting as a facade for a set of related entity beans,
can copy data from multiple entity beans into serializable value objects, and
return this data in a single remote call. This is described in detail in Core
J2EE Patterns - Value Object Pattern ([ALU01].
This must be balanced by the concerns of keeping interfaces as general as possible,
and avoiding sending too much un-needed data.
Demarcating transactions means initiating, committing and aborting transactions.
An EJB designer must decide whether to implement bean-managed transaction demarcation
or container-managed transaction demarcation. You must decide on the locations
of the transaction boundaries in the sequences of business logic performed by
your application. For more information, see Activity: Use-Case Design, Modeling Transactions
and the section titled Transaction Management
in Concepts: J2EE Overview.
Use container-managed transactions where possible. This will keep your code
simple and allow developers to focus on the business logic of the application.
In general, larger granularity transactions will result in better overall
performance. Suppose you make a sequence of method calls to an EJB (for example,
getX, getY and setZ). By default, each method will execute in a new transaction,
resulting in reduced performance. To call these within the same transaction,
create another method, for example method processXYZ of a session EJB, and set
the transaction attributes of the called methods to Required, so that
they use the existing transaction (i.e. the transaction of the calling method
in the session bean).
Basic EJB security concepts are covered in Concepts:
J2EE Platform Overview - Security.
You define your EJB?s security requirements by defining security roles
and method permissions. Security roles and method permissions are
defined in the EJB?s deployment descriptor. It is up to the server (using
administration tools) to map security roles onto users or groups of users.
A security role defines a set of similar types of activities that are grouped
under a single name. A method permission grants a particular security role the
right to call the method. For example, consider an entity EJB Employee,
with methods setAddress, setSalary etc. A security role of manager
may be granted method permission for the methods setAddress and setSalary, while
a security role of employee may only be granted method permission for
the method setAddress.
In some situations it is impossible to support the security requirements of
an application using declarative method permissions in the deployment descriptor.
In this case you use the getCallerPrincipal and isCallerInRole methods of the
javax.ejb.EJBContext interface.
Since J2EE 1.4 (more exactly EJB 2.1) stateless sessions
beans and message-driven beans can use timers to schedule batch processes through
the EJB Timer Service.
The EJB Timer Service that provides methods to allow
callbacks to be scheduled for time-based events. The container provides a reliable
and transactional notification service for timed events. Timer notifications
may be scheduled to occur at a specific time, after a specific elapsed duration,
or at specific recurring intervals.
The Timer Service is implemented by the EJB container
and an enterprise bean can access this service through the EJBContext interface.
The EJB Timer Service is a coarse-grained timer notification
service that is designed for use in the modeling of application-level processes
and not intended for modeling real-time events.
Direct Access vs. Entity beans
Using entity beans for persistent data provides a standard, feature-rich mechanism
for accessing persistent data. The decision to use bean-managed persistence
or container-managed persistence can be hidden from clients, giving the design
some flexibility. EJBs can take advantage of transactions, resource management,
load-balancing, and other features provided by the J2EE environment.
However, there could be situations where you might want to access the database
directly and avoid using entity beans. For example, if the data is always accessed
as read-only by a single client, direct access to the database would be more
efficient.
If you're accessing the database directly (for example, from a stateless session
bean), encapsulate all database access within a Data Access Object class. This
is just a Java class that hides and encapsulates the underlying storage mechanism,
and isolates changes when, and if, the interface to the data source changes.
See Core J2EE Patterns - Data Access Object Pattern ([ALU01].
Virtually all EJB containers provide support for connection pooling-sharing
a set of already-created connections between clients. These connections are
assigned to EJBs as needed. The EJB profits by obtaining a connection without
the expense of creating and initializing it. When the connection is returned
to the pool, it's recycled. The size of the pool should have enough ready connections
available to recycle the used ones.
For entity beans with container-managed persistence, the container manages
the database connection and access to the database connection pool.
For entity beans with bean-managed persistence (or for session or message-driven
EJBs that access a database), the developer is responsible for coding the connection
routine. The following guidelines apply:
- Isolate your database access code in a DAO class.
- Don't hardcode the actual URL of the database-instead, use a logical
name that can be retrieved using Java Naming and Directory Interface (JNDI)
lookup. This allows you to reuse the EJB in multiple applications, possibly
with different database names.
- In general, use connection pools, and only hold the connection for as long
as it's needed. For example, an entity bean might connect, update a row in
a table, and then disconnect. This will allow many EJBs to share the same
connection. The JDBC specification includes support for connection pooling.
|