Book Home Enterprise JavaBeans Search this book

9.4. Bean Adapters

One of the most awkward aspects of the EJB bean interface types is that, in some cases, the callback methods are never used or are not relevant to the bean at all. A simple container-managed entity bean might have empty implementations for its ejbLoad(), ejbStore(), ejbActivate(), ejbPassivate(), or even its setEntityContext() methods. Stateless session beans provide an even better example of unnecessary callback methods: they must implement the ejbActivate() and ejbPassivate() methods even though these methods are never invoked!

To simplify the appearance of the bean class definitions, we can introduce adapter classes that hide callback methods that are never used or that have minimal implementations. Here is an adapter for the entity bean that provides empty implementations of all the EntityBean methods:

public class EntityAdapter implements javax.ejb.EntityBean {
    public EntityContext ejbContext;

    public void ejbActivate(){}
    public void ejbPassivate(){}
    public void ejbLoad(){}
    public void ejbStore(){}
    public void ejbRemove(){}

    public void setEntityContext(EntityContext ctx) {
        ejbContext = ctx;
    }
    public void unsetEntityContext() {
        ejbContext = null;
    }
    public EntityContext getEJBContext() {
        return ejbContext;
    }
}

We took care of capturing the EntityContext for use by the subclass. We can do this because most entity beans implement the context methods in exactly this way. We simply leverage the adapter class to manage this logic for our subclasses.

The bean class then extends this adapter class. Here's a modified version of the CabinBean class that uses the EntityAdapter to reduce the clutter of empty callback methods. Compare this definition of the CabinBean with the one from Chapter 2, "Architectural Overview".

public class CabinBean extends EntityAdapter {

    public int id;
    public String name;
    public int deckLevel;
    public int shipID;
    public int bedCount;

    public int getShipID() {
        return shipID;
    }
    public void setShipID(int ship) {
        shipID = ship;
    }
    public CabinPK ejbCreate(int id) {
        // EJB 1.0 return type is void
        this.id = id;
        return null;
    }
    public void ejbPostCreate(int id) {
        // Do nothing. Required.
    }
    public String getName() {
        return name;
    }
    public void setName(String str) {
        name = str;
    }
    public int getBedCount() {
        return bedCount;
    }
    public void setBedCount(int bc) {
        bedCount = bc;
    }
    public int getDeckLevel() {
        return deckLevel;
    }
    public void setDeckLevel(int level) {
        deckLevel = level;
    }
}

If a callback method is deemed necessary, it can simply be overridden by a method in the bean class.

A similar Adapter class can be created for stateless session beans:

public class SessionAdapter implements javax.ejb.SessionBean {
    public SessionContext ejbContext;

    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void ejbRemove() {}

    public void setSessionContext(SessionContext ctx) {
        ejbContext = ctx;
    }
    public SessionContext getEJBContext() {
        return ejbContext;
    }
}

Don't use these adapter classes when you need to override more than one or two of their methods. If you need to implement several of the callback methods, your code will be clearer if you don't use the adapter class. The adapter class also impacts the inheritance hierarchy of the bean class. If later you would like to implement a different superclass, one that captures business logic, the class inheritance would need to be modified.



Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.