Building Portable Entity Beans

   

You saw in the preceding chapter that using BMP means that you're responsible for coding the database calls needed to persist an entity bean. You do this using JDBC or an ORM framework that manages the mapping of object attributes to database tables. Whichever API you choose, a BMP bean class has to load and save its assigned entity object and that entity's dependent objects as directed by the container. The container makes synchronization requests to an entity instance by invoking its callback methods ( ejbLoad and ejbStore , among others). This approach gives you a great deal of control over how an entity bean is persisted and retrieved. The drawback is that you have to write and maintain the persistence code for an entity instead of being able to focus only on its business logic.

This chapter explains the alternative to BMP. Instead of coding the database access needed to manage an entity's persistent state, you can provide a set of declarative mappings and let the container generate the necessary JDBC calls for you. You give up some of the flexibility of BMP, but, with container-managed persistence (CMP), you also give up some of the coding needed to implement an entity bean. Using CMP, you're responsible for identifying the persistent attributes of an entity bean and defining its relationships with other entities, but you don't have to write any database access code.

The EJB 1.1 Specification defined CMP and required all container implementations to support it, but it left most of the details up to the individual vendors . This resulted in a wide range of functionality across implementations. It also made it difficult to port between implementations. Even though mappings between entity fields and database columns were done declaratively , there was no standard syntax. Porting to another application server usually meant using another CMP implementation, which would almost certainly require redoing the database mappings. There were a few exceptions offered by third party products, but developers who required application server portability often looked toward BMP as the only attractive choice.

A major goal of EJB 2.0 is to alleviate the portability problems of CMP. The requirements for CMP are now specified in such a way that an entity bean implemented using CMP is much more portable to another compliant container. When you implement a CMP bean, you can reuse the same bean class and the deployment information that defines its persistent fields, relationships, and finder method queries with another container. The only part of the deployment that's still vendor-specific is the pairing of persistent fields and database columns. Because these mappings are defined in a deployment descriptor, it's possible to change databases without changing (or recompiling) your entity bean classes.

CMP and Dependent Objects

As you've seen through the auction example, managing dependent objects isn't too difficult when you use BMP. It takes some work, but writing your own persistence code gives you the flexibility you need to manage whatever relationships your application requires. CMP presents a more complicated problem because the container must have a predetermined way to persist objects and manage the relationships between them. Early drafts of the EJB 2.0 Specification included support for managing dependent objects using CMP. This would have allowed you to provide declarative descriptions of your dependent objects so that the container could implement the operations required to persist them. Even better, the container would have been required to maintain the relationships between them and your entity beans. However, the idea of standardizing support for dependent objects went away with the introduction of local clients. Even though this might seem like a setback, local clients have more to offer when you consider both options.

The entity beans exposed to your session bean clients are expected to be coarse-grained objects that provide something significant in terms of data or business logic. You'll often hear entity beans described as being "heavyweight" because of the overhead incurred from the container's security and transaction management when they're accessed remotely. Because dependent objects typically are maintained behind a facade provided by an entity bean, they are instead viewed as lightweight objects that don't require the overhead that comes with remote access. This viewpoint drives the idea of implementing lightweight dependent objects as something other than entity beans. The criticism directed toward using entity beans for lightweight objects has been based primarily on the performance cost of remote calls.

Some EJB 1.1 vendors optimized calls among beans in the same container to minimize the performance penalty of remote calls. Local interfaces and local homes make this type of optimization standard in EJB 2.0. If the container were to support dependent objects as part of CMP, this definitely would offer a way to reduce the overhead of accessing your lightweight persistent objects. With this approach, the calls between an entity and its dependents could be executed efficiently by avoiding the additional work required when exposing a persistent object to a remote client. However, this would be only a partial solution because it wouldn't do anything to help the calls made to the coarse-grained objects you did choose to implement as entity beans.

By supporting local interfaces, EJB 2.0 CMP improves the efficiency of interactions between persistent objects while also providing a similar benefit to session and message-driven beans that access entity beans deployed in the same container. Beyond the technical advantages of local interfaces, using entity beans for all your persistent classes also offers you the practical bonus of having to learn only a single implementation approach. Instead of having to choose between an entity bean and a regular Java class, you only have to worry about whether or not to expose a remote interface when you're creating a persistent class. Local interfaces easily have the potential to be more far-reaching than formalized dependent objects in their positive impact on your applications.

Even though you must implement what you would normally code as a regular Java class if you were using BMP as an entity bean when using CMP, you still can design and deploy your applications so that these classes are accessed only by the coarse-grained entity beans that maintain them. Just as the EnglishAuction bean hid its interaction with instances of Bid when using BMP, you can build an application where the auction entity interacts with an equivalent entity bean version of Bid that is never directly accessed by the session bean clients. If you use remote clients for your session beans, you can control which entity beans are exposed simply by limiting which beans support a remote interface.

Note

Even though the specification doesn't address dependent objects for CMP, this doesn't mean that you won't find implementations that do. Even prior to EJB 2.0, CMP implementations existed that went well beyond the specification. For example, WebGain's TOPLink for WebLogic and TOPLink for WebSphere products provide CMP solutions for EJB 1.1 that allow you to manage the persistence of both entity beans and their dependent objects. At the time of this writing, no EJB 2.0 version of a product such as these was available, but that won't be true for long.


Transitioning the Auction Example to CMP

This chapter describes the steps needed to implement the auction example using CMP. Portions of the resulting source code are included in the text of the chapter as topics are introduced. The complete source listings are included on the accompanying CD. The example is developed in such a way that the CMP entity beans can coexist in the same source tree with their BMP counterparts. To make this possible, some care has to be taken in how the new classes are named. For example, the auction bean CMP implementation class is named EnglishAuctionCMPBean to distinguish it from EnglishAuctionBean . The same approach is used for ItemCMPBean and BidderCMPBean . This wouldn't be necessary in typical circumstances because you would have only a single implementation of each bean. Changes to the dependent object names are also necessary when rewriting them as entity beans. For example, the Bid dependent object is implemented as AuctionBidBean to avoid the name collision that would result from naming its local interface Bid . Address is implemented as StreetAddressBean for the same reason. Because these objects are hidden behind the auction and bidder beans and exposed only through their corresponding view classes, clients of the entities are unaffected by these changes. As far as the clients are concerned , the auction and bidder entities are still coarse-grained objects that encapsulate their supporting classes.



Special Edition Using Enterprise JavaBeans 2.0
Special Edition Using Enterprise JavaBeans 2.0
ISBN: 0789725673
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net