Tip 2 - Bulk Accessors in Entity Beans

August 30th, 1999
In the Design Strategies chapter of the book Enterprise JavaBeans the dangers of pass-by-value in distributed computing is discussed in detail.  The biggest danger associated with pass-by-value is object equivalence which is explained in the following quote from page 260
"The pass-by-value section earlier gave you some good ground rules as to when a business concept should be modeled as a pass-by-value object. Business concepts that do not meet the pass-by-value criteria should be modeled as either session or entity beans. Many inexperienced distributed object developers adopt a strategy of passing small-grained business objects, that would normally qualify as entity beans (Customer, Ship, and City), by value to the clients. The belief is that passing the entity objects to the client avoids unnecessary network traffic by keeping the set and get methods local. The problem with this approach is object equivalence. Entities are supposed to represent the actual data on the database, which means that they are shared and always reflect the current state of the data. Once an object is resident on the client, it is no longer representative of the data. It is easy for a client to end up with many dirty copies of the same entity, resulting in inconsistent processing and representation of data."
Most entity beans have several persistent fields, which are manipulated through accessor methods. Unfortunately, the one-to-one nature of the accessor idiom can result in many invocations when editing an entity, which translates into a lot of network traffic for even simple edits.  One strategy that reduces the network traffic when editing entities is the Bulk Accessor strategy.

In the Bulk Accessor strategy, access to several persistent fields is packaged into one accessor, a bulk accessor.  Bulk accessors provide get and set methods that work with structures or simple pass-by-value objects.  Below is an example of how this would work with the Cabin bean, which is used through out the book.

CabinBean with Bulk Accessors  CabinData Bulk Accessor data object
public class CabinBean implements javax.ejb.EntityBean { 
    public int id; 
    public String name; 
    public int deckLevel; 
    public int ship; 
    public int bedCount; 
    // bulk accessors 
    public CabinData getData( ){ 
        return new CabinData(name,deckLevel,bedCount); 
    public void setData(CabinData data){ 
        name = data.name; 
        deckLevel = data.deckLevel; 
        bedCount = data.bedCount; 
    // simple accessors and entity methods 
    public String getName(){ 
        return name; 
    public void setName(String str){ 
        name = str; 
     // more methods follow 
public class CabinData implements java.io.Serializable {
    public String name;
    public int deckLevel;
    public int bedCount;
    public CabinData( ){
    public CabinData(String name, int deckLevel, int bedCount){ 
        this.name = name; 
        this.deckLevel = deckLevel; 
        this.bedCount = bedCount; 

The getData( ) and setData(..) bulk accessor methods allow several fields to be packaged into a simple object and passed between the client and bean in one method call.  This approach can significantly reduce network traffic especially when many fields need to be edited.

Rules-of-thumb for Bulk Accessors

  Data Object are Simple Structs

Keep the data object as simple as possible; ideally they are limited to a struct like objects.  In other words, the data object should not have any business logic at all, it should only have fields.  While we want to avoid excessive network traffic, we do not want to pass business objects by value.   All the business logic should remain in the entity bean where its is centralized and easily maintained.  Placing business logic into the data object will unnecessary partition the logic between two constructs and encroach on object equivalency problems sited above.  In addition, some EJB systems based on CORBA 2.0 may not be capable of passing complex objects by value.  In these cases, only simple structures, without behavior, can be passed.  This is why the fields of the data object are public, which is consistent with the primary key and dependent object designs examined in the book.

In order to keep the semantics of a struct, data objects should not have accessor (get/set) methods for reading and writing the fields.  If you take a look at the CabinData class in the example above you will notice that it doesn't have accessor methods, just fields and a couple of constructors.  The lack of accessors reinforces the idea that the purpose of the data object is to bundle fields together, not to "behave" in a particular manner.  As a design concept we want the data object to be a simple structure devoid of behavior; it's a matter of form following function.  The exception is the multi-argument constructor which is left as a convenience for the developer.

 Bulk Accessors bundle related fields
The bulk accessors can pass a subset of the entities data.  Some fields may have different security or transaction needs which require that they be accessed separately.  In the CabinBean example above, only a subset of the fields (name, deckLevel, bedCount) are passed in the data object.  This id field is not included for several reasons: It doesn't describe the business concept, it's already found in the primary key, and it should not be edited by the client.  The ship field is not passed because it should only be updated by certain individuals; the identities authorized to changes this field are different.  In addition, the ship field may fall under a different transaction isolation level (TRANSACTION_SERIALIABLE) than the other fields (TRANSACTION_READ_COMMITED), the differences of which are explained in detail in the book.

In addition, its more efficient to design bulk accessors that pass logically related fields.  In entity beans with many fields its possible to group certain fields that are normally edited together.  An employee bean, for example, might have several fields that are demographic in nature (address, phone, e-mail) that can be logically separated from other fields like ones that are specific to benefits (compensation, 401K, health, vacation).  Logically related fields can have their own bulk accessor, and its possible that several bulk accessors would be on the same bean. Below is an example:

Remote interface with multiple bulk accessors
public interface EmployeeBean extends java.ejb.EJBObject { 
    public EmployeeBenefitsData getBenefitsData( ) throws RemoteException; 
    public void setBenefitsData(EmployeeBenefitsData data) throws RemoteException; 
    public EmployeeDemographicData getDemographicData( ) throws RemoteException; 
    public void setDemographicData(EmployeeDemographicData data) throws RemoteException; 
    // more simple accessors and other business methods follow 

Retain simple accessors

Simple Accessors (get and set methods for single fields) should not be abandoned when using bulk accessors.  Simple accessors should be maintained in the remote interface of the entity bean to allow editing of single fields.  It's just as wasteful to use a bulk accessor to change one field as it is to change several fields using simple accessors.

Back to Top