Inheritance and Entity Beans

   

Inheritance is central in object-oriented design, but it's a topic that, for the most part, is sidestepped by the EJB specification. It's not that you're prevented from using inheritance with your EJBs, but there are a few issues to consider when you do. The central question relates to the type of inheritance that you implement.

In an ideal world, you could seamlessly define a hierarchy of entity bean classes and corresponding home and component interface hierarchies. Here an entity bean and all its constituent parts could be declared to extend some other entity bean without any special consideration on your part. This resulting component inheritance would reflect what you typically do with regular Java classes by allowing you to treat any subclass like the common superclass. This concept carries over quite well to entity bean classes and component interfaces. Inheritance in this case is handled as the normal addition of method implementations and any accompanying overrides . Home interfaces are not quite as simple, though.

When you declare create and single-object finder methods in a home interface, you declare their return type to be the corresponding component interface type. The corresponding ejbCreate and ejbFind methods in the implementation class must be declared to return the primary key type, though. It's important to remember here that it's illegal for two methods in a class hierarchy to have signatures that differ only in return type. This creates a problem if the primary key class in a hierarchy of EJB classes isn't the same for every class. This issue is the primary reason mentioned by the EJB 2.0 Specification for not supporting transparent component inheritance. A possible solution is to declare the primary key to be Object , but that limits the knowledge of the key class that bean methods and clients can use. The home interface and parts of the bean implementation must operate in a generic manner for this to work. This is basically the same as deferring the primary key choice until deployment that was discussed earlier in the chapter.

Finder methods bring up a limitation of home interface inheritance as well. Intuitively, calling a finder method on the home interface of an entity bean with subclasses should produce results that include references to any subclass instances that fit the criteria used by the finder. It might be possible to achieve this using BMP by applying some knowledge of the subclasses, but it won't be the case for CMP. Instead, you'd have to implement a home method or a session bean method that called the individual finders and consolidated the results for return to the client.

Declaring an Entity Bean Class Hierarchy

Although it's true that you should avoid inheritance of home interfaces in general, you shouldn't avoid inheritance altogether. Inheritance within bean class implementations and component interfaces allows you to build a certain amount of layering into a design, just as you would if you weren't using EJBs. What you typically do to avoid any issues with home interfaces, though, is to stop subclassing when you reach the first concrete entity bean along a branch in the inheritance tree. The first step in this approach is to create an abstract implementation of EntityBean , as shown in Listing 5.11.

Listing 5.11 AbstractEntity.java “An Abstract Implementation of EntityBean
 package com.que.ejb20.common.ejb;  /**   * Title:        AbstractEntity<p>   * Description:  Abstract class for entity beans. This class implements   *   setEntityContext and unsetEntityContext and provides do-nothing   *   implementations for the other methods declared by EntityBean.<p>   */  import javax.ejb.EntityBean;  import javax.ejb.EntityContext;  import javax.ejb.RemoveException;  public abstract class AbstractEntity implements EntityBean {   protected EntityContext ctx;    public void ejbActivate() {}    public void ejbLoad() {}    public void ejbPassivate() {}    public void ejbRemove() throws RemoveException {}    public void ejbStore() {}    public void setEntityContext(EntityContext newCtx) {     ctx = newCtx;    }    public void unsetEntityContext() {     ctx = null;    }  } 

The implementation of AbstractEntity does little more than manage the assignment of the EntityContext , but even that reduces what you have to implement in a concrete entity class. This class also provides do-nothing implementations of the container callback methods, which, as you'll see in Chapter 7, is often all you need when you're using CMP. If your design called for any other behavior common to all entity beans, a class like AbstractEntity would provide a place to implement that also.

Note

Declaring a base class that implements an interface by providing do-nothing implementations of its methods is a well-established pattern in object-oriented design. This approach is documented as the Adapter pattern in Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. If you only need to implement behavior for a subset of an interface's methods, you can extend an Adapter for the interface and override the methods you care about. This frees your classes from being cluttered with methods that don't do anything.


You can next build on AbstractEntity to define application-specific behavior. This can mean extending AbstractEntity to declare your concrete entity beans or it might mean having one or more other layers in between them. Suppose, for example, that the requirements for the auction site included supporting both English and reverse auctions. You might want to extend AbstractEntity to define the behavior common to both auction types in a class called AbstractAuction . You could then extend AbstractAuction to define EnglishAuctionBean and ReverseAuctionBean classes. The business methods implemented by the auction classes could be defined by a parallel set of interfaces. Each bean's component interface would be declared to extend its corresponding business method interface in addition to EJBObject or EJBLocalObject . You'll see this topic discussed more in Chapter 16.

What this approach doesn't address is any inheritance of the home interfaces. The EnglishAuctionHome and ReverseAuctionHome interfaces would be independent. Because there aren't any concrete entity beans that are superclasses of other beans, this isn't too much of a limitation. Figure 5.2 shows the resulting relationship between the classes and interfaces.

Figure 5.2. Creating a hierarchy of component interfaces and bean classes allows you to layer a design.

graphics/05fig02.gif



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