Dependent Value Classes

As discussed in the previous section, dependent value classes are custom serializable objects that can be used as persistence fields—(although this use is not recommended). Dependent value classes are useful for packaging data and moving it between an entity bean and its remote clients. They separate the client’s view of the entity bean from its abstract persistence model, which makes it easier for the entity bean class to change without impacting existing clients.

The remote interface methods of an entity bean should be defined independently of the anticipated abstract persistence schema. In other words, you should design the remote interfaces to model the business concepts, not the underlying persistence programming model. Dependent value classes can help separate a remote client’s view from the persistence model by providing objects that fill the gaps in these perspectives. Dependent value classes are used a lot in remote interfaces where packaging data together can reduce network traffic, but are less useful in local interfaces.

For example, the CustomerEJB could be modified so that its lastName and firstName fields are not exposed directly to remote clients through their accessor methods. This is a reasonable design approach, since most clients access the entire name of the customer at once. In this case, the remote interface might be modified to look as follows:

import java.rmi.RemoteException;

public interface CustomerRemote extends javax.ejb.EJBObject {
       
    public Name getName() throws RemoteException;
    public void setName(Name name) throws RemoteException;
    
}

The remote interface here is simpler than the one we saw earlier. It allows the remote client to get all the name information in one method call instead of two—this reduces network traffic and improves performance for remote clients. The use of the Name dependent value is also semantically more consistent with how the client interacts with the Customer EJB.

To implement this interface, the CustomerBean class adds a business method that matches the remote interface methods. The setName() method updates the lastName and firstName fields, while the getName() method constructs a Name object from these fields:

import javax.ejb.EntityContext;

public abstract class CustomerBean implements javax.ejb.EntityBean {
       
    public Integer ejbCreate(Integer id){
        setId(id);
        return null;
    }
    public void ejbPostCreate(Integer id) {
    }
    // business methods
    public Name getName() {
        Name name = new Name(getLastName(),getFirstName());
        return name;
    }
    public void setName(Name name) {
        setLastName(name.getLastName());
        setFirstName(name.getFirstName());
    }

    // abstract accessor methods

    public abstract String getLastName();
    public abstract void setLastName(String lname);
    
    public abstract String getFirstName();
    public abstract void setFirstName(String fname);

This is a good example of how dependent value classes can be used to separate the client’s view from the abstract persistence schema.

The getName() and setName() methods are not abstract persistence methods, they are business methods. Entity beans can have as many business methods as needed. Business methods introduce business logic to the Customer EJB; otherwise, the bean would be only a data wrapper. For example, validation logic could be added to the setName() method to ensure that the data is correct before applying the update. In addition, the entity bean class can use other methods that help with processing data—these are just instance methods and may not be exposed as business methods in the remote interface.

How dependent value classes are defined is important to understanding how they should be used. The Name dependent value class is defined as follows:

public class Name implements java.io.Serializable {
    private String lastName;
    private String firstName;
    
    public Name(String lname, String fname){
        lastName = lname;
        firstName = fname;
    }
    public String getLastName() {
        return lastName;
    }
    public String getFirstName() {
        return firstName;
    }
}

You’ll notice that the Name dependent value class has get accessor methods but not set methods. It’s immutable. This is a design strategy used in this book, not a requirement of the specification; CMP 2.0 does not specify how dependent value classes are defined. We make dependent values immutable so that “remote clients cannot change the Name object’s fields. The reason is simple: the Name object is a copy, not a remote reference. Changes to Name objects are not reflected in the database. Making the Name immutable helps to ensure that clients do not mistake this dependent value for a remote object reference, thinking that a change to the Name object is automatically reflected in the database. To change the customer’s name, the client is required to create a new Name object and use the setName() method to update the Customer EJB.

The following code listing illustrates how a client would modify the name of a customer using the Name dependent value class:

// find Customer
customer = home.findByPrimaryKey(primaryKey);
name = customer.getName();
System.out.print(primaryKey+" = ");
System.out.println(name.getFirstName()+" "+name.getLastName());
                                    
// change Customer's name
name = new Name("Monson-Haefel", "Richard");
customer.setName(name);
name = customer.getName();
System.out.print(primaryKey+" = ");
System.out.println(name.getFirstName()+" "+name.getLastName());

The output will look like this:

1 = Richard Monson
1 = Richard Monson-Haefel

Defining the bean’s interfaces according to the business concept and not the underlying data is not always reasonable, but you should try to employ this strategy when the underlying data model doesn’t clearly map to the business purpose or concept being modeled by the entity bean. The bean’s interfaces may be used by developers who know the business but not the abstract programming model. It is important to them that the entity beans reflect the business concept. In addition, defining the interfaces independently of the persistence model enables the component interfaces and persistence model to evolve separately. This allows the abstract persistence programming model to change over time and allows for new behavior to be added to the entity bean as needed.

While the dependent value classes serve a purpose, they should not be used indiscriminately. Generally speaking, it is foolish to use dependent value classes when a CMP field will do just fine. For example, checking a client’s credit worthiness before processing an order can be accomplished easily using the getHasGoodCredit() method directly. In this case, a dependent value class would serve no purpose.

Dependent Value ClassesPlease refer to Workbook Exercise 6.2, Dependent Value Classes in CMP 2.0. This workbook is available free, in PDF format, at http://www.oreilly.com/catalog/entjbeans3/workbooks.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset