Oracle9iAS TopLink CMP for Users of BEA WebLogic Guide Release 2 (9.0.3) Part Number B10065-01 |
|
Enterprise JavaBeans present a way to build components as well as a means to make these components exist in a transactional, secure, and distributed environment. However, a single bean represents only one component - and consequently only one part of a complete application. EJB provides developers with flexibility in determining how these components should be made to work together. There are a number of ways in which Enterprise JavaBeans can be made to work together to form a complete enterprise application. TopLink can be integrated into each variety of EJB application architecture to provide both the technology that enables these architectures and the features that add value to them.
This chapter gives an overview of some of the basic design patterns available when using TopLink and TopLink CMP. It is not meant to be prescriptive and neither is it complete. It briefly suggests some of the more useful EJB designs and their suitability to specific applications. Architects and developers may find these sections useful at the early stages of application design. As more experience is acquired the appropriateness of particular patterns will become more obvious, and architectural decisions will be more intuitively reached.
The basic ways in which EJBs can be assembled, or the basic "EJB architectures", can be described in terms of which kinds of beans or J2EE components are used, how client applications access them, and how the underlying "domain objects" are represented. The EJB architectures can be fundamentally divided into three categories: an Entity bean architecture, a Session bean architecture, and a Session and Entity "tiered" approach. Each basic architecture also has variations and refinements and can be decorated with a variety of J2EE components.
The EJB 2.0 specification does not dictate how enterprise entities are used, but it is clear from the evolution of the specification that certain architectures were assumed to be dominant. Some of the recommended architectures are explained in the J2EE Blueprints (see http://java.sun.com/blueprints). These documents should be reviewed for more information about J2EE and EJB architectures.
If entities alone are used then they must have remote interfaces that expose all of the client servicing methods. In the absence of Session beans, the client may only access entity state through its remote interface, and may not traverse relationships, except as encapsulated by remote method calls. Only remote references and data may be returned by these calls. Finders may only return remote references as well.
If relationships do exist then they must be implemented using local interfaces, hence there must be different levels of access from the remote and local interfaces. References to related entities must be translated from local to remote references if they are to be passed back from remote client calls.
Clients gain from this approach in that the distribution of the entities is transparent. Clients reference the entities as if they were local, and do not need to worry about location. Entities can exist at different locations without the client even being aware of it.
The converse of transparent distribution is that if clients are not aware of the distributed nature of the entities then they may not be aware of the cost of invoking them. If the entities are "fine-grained" objects then each fine-grained method invocation on them will end up being a remote call. The accumulation of these remote method invocations could sum up to a potentially serious network or communication latency cost.
If Container transactions are used for each entity operation a separate transaction will end up being initiated for each method invocation. This could introduce excessive and unnecessary transaction management overhead if client-demarcated UserTransactions are not used.
Since Entity beans are intended to be "components" there are more restrictions placed on them than on regular Java objects (e.g. thread-spawning is disallowed). This may impose limits on how they can be used to model certain domain concepts. The limitations should be well understood and compared against the model to ensure that they are not discovered too late in the design phase.
In general, however, this architecture is less desirable than other architecture types. The relationship limitations imposed by the EJB 2.0 specification are often an impediment to using this approach.
It is common practice to apply a Session bean layer in front of lightweight objects. This may take the form of the session façade pattern described below, with lightweight entities or other types of persistent objects being managed.
Since Session beans do not themselves represent durable objects, often a session façade pattern will be used to converse directly with persistent Java objects, without the use of entities. Persistent data can be modeled using regular TopLink-enabled persistent Java objects that are managed by the Session beans and mapped using TopLink tools. Since few domain objects actually "live" on the client, client applications rarely need to access the domain objects directly, but if regular objects are used then they may be sent to the client if necessary since no such restriction exists for them. The Session beans are used to carry out most of the application logic. Stateful beans are used for those operations for which client-identity is important, while stateless Session beans can be used for "single-shot" operations. All of the EJB benefits of security, transactions and distribution are available through the Session beans.
The exclusive use of Session beans does not allow for overly complex client behavior - all client behavior is limited to services provided by the Session beans. Simple client behavior is a general characteristic of all thin client architectures.
Simplicity and fast client access are clear benefits of this approach. In addition, there is great flexibility in how the domain objects are designed, and how these objects are mapped to the underlying relational database tables.
The majority of systems have relationships between application entities. This being the expected scenario, it is well observed and explained by J2EE designers. The EJB 2.0 specification dictates that all such related entities must be co-located within the same server, or running in the same VM. Such a requirement to use local interfaces to entities both enforces transactional integrity of relationships and opens the door to substantial optimization of entity invocation.
The problem of accessing the local entities on the server from a remote Java client is overcome by installing a session bean that exports the required client operations through a remote interface, as was described in the above section. The client application, then, converses only with the session bean and passes all of its data and requests to the session bean for service. The client may still retain much of the logic, if so desired, with the session bean making fine-grained operations on the local entities. More common, however, is to incorporate the domain logic into the session bean itself. This migrates the business logic from the client to the server which provides a number of well-known benefits including ease of maintenance, convenient upgradability, and increased access to server features.
Regardless of whether the session bean simply forwards operations to entities or actually includes the application logic as a façade that fronts the local entities it is a modular approach to remotely accessing server-side objects. It is also likely to be easier to maintain as the J2EE specification moves forward, since session beans tend to experience change to a lesser degree than other components, such as entities. The decision to use a stateful or stateless session bean will likely depend on the amount of business logic incorporated into the session bean.
A prevalent B2B architecture uses an HTTP browser as its client and makes use of J2EE servlet and JSP components to contain the presentation and sometimes even business logic. These layers then typically invoke EJB's for transactional behavior. Although the EJB specification seems to treat server-side components as remote the J2EE specification does allow ejb-ref and ejf-local-ref elements to be added they are still, according to the EJB specification, remote clients to the EJB's. Some servers, however, support the definition of ejb-refs or ejb-local-refs in the descriptors of these components, which will enable invocation of referenced EJB's. This allowance takes into consideration the fact that these components are all co-located and that local entity access could occur.
A stricter and more portable approach would be to retain the session façade layer described in the above section. This would require the JSP to remotely access a session bean, which in turn would invoke the local entities. This layered J2EE structure divides the responsibilities of the system up into its various components, and allows substitution or upgrading of a single component with little or no effect on the others.
There are a good many applications that make use of persistent data objects that are not autonomous, or that do not require their own transactional and security mechanisms. Instead they would be better suited to share, or "piggy-back" on top of the mechanisms of an existing object upon which they rely. This secondary or reliant object is called a dependent object.
Dependent objects may take one of three forms. They may appear as local entity beans residing only on the server. They may be simple persistent TopLink-enabled Java objects that can be shipped back and forth between the client and server. They may even be serializable "dependent value" objects that are persisted by simply attaching them to entities and letting their contents be serialized when the entity gets written back to its persistent store. Each of these three strategies has its advantages and may apply more readily in certain applications.
Strictly speaking, EJB local entities should not be considered lightweight since all of the container security, transactional and synchronization costs are still very much in effect. They are included in this category chiefly because they are more lightweight than remote entities and because they can, in practice be used as dependent objects. But they are not considered to be truly "dependent", in the sense that they can be "found" (using finder methods on the home interface) by any server-side component regardless as to whether they are related to the object or not.
Because EJB Containers can assume that local entities are always co-located in the same VM, communication optimizations can be effected by the Container. Local entity methods can be invoked using pass-by-reference semantics, alleviating unnecessary marshalling and communications infrastructure costs. This makes them lighter than remote entities both in the amount of code that gets generated by the Container, and the execution time of each method invocation.
The EJB 2.0 specification discusses a class of object called a dependent value object that can be assigned to an entity attribute. They are nothing more than regular serializable Java objects and must be serialized in their entirety and written out in BLOB form when any part of them changes. It is an integral part of the entity since it is stored as a "cmp" field in the entity. Although it can be sent across from client to server and back again, its persistence is coupled with the entity and it is not practical when multiple levels of dependent objects are required.
Because of TopLink's ability to persist regular Java objects without the need for EJB container support these objects offer the most flexibility. They do not incur the entity costs of container management but can be persisted independent of the entity. This means that changes are detected at commit-time, but if nothing changes during the course of an entity update then the object will not be written back, and likewise only the object may be written out if the reverse is true. The dependency upon the entity is still intact, however, as any removal of the entity will automatically propagate to cause the dependent Java object to be removed from persistent storage. Like serializable value objects, they can be transported back and forth between the client and server, allowing for client interactions that refer to the owning bean, but operate on the dependent data. These objects are not supported in the EJB 2.0 specification, but do offer the benefits of managed, mapped persistence.
EJB provides developers with a great deal of infrastructure that makes building enterprise applications easier. This allows developers to build better applications by allowing them to focus on the business logic of their application rather than on distribution, security, and transactions. Even with everything that EJB provides, developing with EJB requires intelligent architectural choices to be made. Although EJB provides much, it also allows for flexibility so that developers can use it to meet their needs.
Regardless of the EJB architecture used, TopLink will support it by providing the right level of control and transparence appropriate to the architecture. The TopLink persistence framework also adds the value required to customize applications to run at their best, and will play an essential role in enabling customers to successfully develop and deploy their enterprise applications.
|
Copyright © 2002 Oracle Corporation. All Rights Reserved. |
|