Value ObjectContextApplication clients need to exchange data with enterprise beans. ProblemJ2EE applications implement server-side business components as session beans and entity beans. Session beans represent the business services and maintain a one-to-one relationship with the client. Entity beans on the other hand are multi-user, transactional objects representing persistent data. A session bean provides coarse-grained service methods when implemented per the Session Façade pattern. Some of the service methods may return data to the client that invoked the methods. In such cases, the client must invoke the session bean's get methods multiple times until the client obtains values for all the attribute values. Every such method call made to the session bean is potentially remote. An entity bean implements persistent business components. An entity bean exposes the values of its attributes by providing an accessor method (also referred to as a getter or get method) for each attribute. When a client needs the data values from an entity bean, it may invoke the entity bean's get methods multiple times until the client obtains data for every attribute that it needs. Again, like the session bean, every such method call made to the entity bean is potentially remote. Thus, in an EJB application each invocation on a session bean or an entity bean is potentially a remote method invocation that utilizes the network layer regardless of the proximity of the client to the bean. Such invocations on the enterprise beans create an overhead on the network. As the usage of these remote methods increases, application performance can significantly degrade. Therefore, multiple calls to get methods that return single attribute values is inefficient for obtaining data values from an enterprise bean. Enterprise bean method calls may permeate the network layers of the system even if the client and the EJB container holding the entity bean are both running in the same JVM, OS, or physical machine. Some vendors may implement mechanisms to reduce this overhead by using a more direct access approach. Forces
SolutionUse a Value Object to encapsulate the business data. A single method call is used to send and retrieve the Value Object. When the client requests the enterprise bean for the business data, the enterprise bean can construct the Value Object, populate it with its attribute values, and pass it by value to the client. Clients usually require more than one value from an enterprise bean. To reduce the number of remote calls and to avoid the associated overhead, it is best to use value objects to transport the data from the enterprise bean to its client. When an enterprise bean uses a value object, the client makes a single remote method invocation to the enterprise bean to request the value object instead of numerous remote method calls to get individual attribute values. The enterprise bean then constructs a new value object instance and copies the attribute values from its attributes into the newly created value object. It then returns the value object to the client. The client receives the value object and can then invoke its accessor (or getter) methods to get the individual attribute values from the value object. Or, the implementation of the Value Object may be such that makes all attributes public. Because the value object has been passed by value to the client, all calls to the value object instance are local calls instead of remote method invocations. StructureThe following class diagram represents the Value Object pattern in its simplest form.
As shown in this class diagram, the value object is constructed on demand by the enterprise bean and returned to the remote client. However, the Value Object pattern can adopt various strategies depending on requirements. The Strategies section explains these approaches. Participants & ResponsibilitiesThe following sequence diagram shows the interactions for a Value Object pattern.
Client This represents the client of the enterprise bean. The client can be an end-user, as in the case of a rich client application that has been designed to directly access the enterprise beans. BusinessObject The BusinessObject represents a role in this pattern that can be fulfilled by a session bean or an entity bean. The BusinessObject is responsible for creating the value object and returning the ValueObject to the client. The BusinessObject receives the data request from the client and creates a new ValueObject. ValueObject The ValueObject is an arbitrary Java object. The ValueObject may provide a constructor that accepts all the required attributes to create the value object. The constructor may accept all entity bean attribute values that the value object is designed to hold. Typically, the members in the ValueObject are defined as public, thus eliminating the need for get and set methods. If some protection is necessary, then the members could be defined as protected or private, and methods to get are provided to get the values. By offering no methods to set the values, a ValueObject is protected from modification after its creation. If only a few members are allowed to be modified to facilitate updates, then methods to set the values can be provided. Thus, the Value object creation varies depending on an application's requirements. It is a design choice as to whether the ValueObject attributes are private and accessed via getters and setters, or all the attributes are made public. StrategiesThe following strategies are applicable when the enterprise bean is implemented as a session bean or as an entity bean. These strategies are called "Updateable Value Object" and "Multiple Value Objects". In Updateable Value Object strategy, the value object not only carries the values from the BusinessObject to the client, but also can carry the changes required by the client back to the entity. In some cases, it is possible that a single BusinessObject produces different value objects depending on the client request. There exists a one-to-many relationship between the BusinessObject and the many value objects it can produce. In these circumstances, the Multiple Value Objects strategy can be considered. "Entity Inherits Value Object" and "Value Objects Factory" strategies are only applicable when the BusinessObject is implemented as an entity bean. When the BusinessObject is implemented as an entity bean, and the clients typically need to access all the data from the entity bean, then the entity bean attributes and the value object attributes are identical. In other words, the value object has all the attributes as the entity bean. In this case, since there exists a one-to-one relationship between that entity bean and its value object, the entity bean may be able to use inheritance to avoid code duplication. Finally, to augment the Entity Inherits Value Object strategy, it is possible to employ a value object factory to create value objects on demand using reflection, resulting in an even more dynamic strategy for value object creation. This strategy is described in the Value Objects Factory strategy below. Updateable Value Objects StrategyThis strategy is also known as the Mutable Value Objects strategy. The following class diagram shows the relationship between the BusinessObject and the value object.
The BusinessObject creates the value object. Recall that a client may need to access the BusinessObject values not only for read-only purposes but to modify these values. For the client to be able to modify the BusinessObject attribute values, the BusinessObject must provide mutator methods. Mutator methods are also referred to as setters or set methods. The BusinessObject can provide a set method for each attribute value that needs updating. However, individual set methods have the same performance limitations, in terms of network overhead, as individual get methods. Rather than providing individual set methods, the BusinessObject can provide a single method-represented by setData(ValueObject)-that accepts a value object. The value object holds the new or modified values and updates the entity bean's attributes with these new or modified values. To accomplish this, the value object must provide both the necessary set and get methods so that the client can not only get the values from the value object, but also change them if required. The entire update interaction is shown in the following sequence diagram. click to enlargeMultiple Value Objects StrategySome application business objects can be very complex. When the business object is implemented as a session bean, usually applying a façade pattern, the bean may interact with numerous other business components to provide the service. The session bean produces its value object from different sources. When the BusinessObject is implemented as a coarse-grained entity bean, usually applying the Aggregate Entity pattern, the entity bean will have complex relationships with a number of dependent objects. In both these cases, it may be a good idea to provide mechanisms to produce value objects that are actually representing parts of the underlying coarse-grained components. For example, in a trading application, an Aggregate Entity that represents a customer portfolio can be a very coarse-grained complex component that can produce value objects that provide data for parts of the portfolio, like customer information, list of stocks held, and so on. A similar example is a customer manager session bean that provides services by interacting with a number of other BusinessObjects and components to provide its service. The customer manager bean can produce discrete small value objects like customer address, contact list, and so on to represent parts of its model. For both these scenarios, it is possible to adopt and apply the multiple value object strategy where the business component, be it a session bean or an entity bean can create multiple types of value objects. In this strategy, the business entity provides various methods to get different value objects. Each such method creates and returns a different type of value object. The class diagram for this strategy is shown below:
When a client needs a value object of type ValueObjectA, it invokes the entity's get data method requesting ValueObjectA. When it needs a value object of type ValueObjectB, it invokes the entity's get data method requesting ValueObjectB, and so on. This is shown in the following sequence diagram.
The following strategies apply to this pattern when the BusinessObject is implemented as an entity bean and are not applicable to session bean implementations. When the value object encapsulates all the attributes of the entity bean, there is a one-to-one relationship between an entity bean and its value object. The entity bean in this case generally produces a value object that contains all the data from the entity bean. Entity Inherits Value Object StrategyIn this strategy, to avoid code duplication, the entity bean can directly extend (or inherit from) the value object class. This pattern strategy is shown in the following class diagram.
The ValueObject implements a getData() method. When this method is invoked on an instance of a ValueObject, it creates a new instance of the ValueObject, copies all values into it and returns it to the caller. When the entity inherits this ValueObject, the entity bean's client invokes this inherited getData() method on the entity bean to obtain a value object. Thus, this strategy eliminates code duplication between the entity and the value object. It also helps manage changes to the value object requirements by isolating the change to the value object class and preventing the changes from affecting the entity bean. This strategy has a tradeoff related to inheritance. If the ValueObject is shared through inheritance, then changes to this ValueObject will affect all its subclasses, potentially mandating other changes to the hierarchy. The following sequence diagram demonstrates this strategy:
The following code sample for an example value object ContactVO illustrates this strategy: // public members // constructor accepting all values // constructor to create a new VO based // method to set all the values // create a new value object } The entity bean sample code relevant to this pattern strategy is shown below.
... // the client calls the getData method ... }
Value Object Factory StrategyThe Entity Inherits Value Object strategy can be extended to support multiple types of Value Objects for an entity bean. To achieve this, define a different interface for each type of ValueObject that must be returned. The entity bean implementation of ValueObject super class must implement all these interfaces. Furthermore, you must create a separate implementation class for each defined interface. (See the example class diagram below). Once all interfaces have been defined and implemented, create a method in the ValueObject Factory that is passed two arguments as follows:
The Value Object Factory can then instantiate an object of the correct class, set its values, and returns the newly created Value Object.
The sequence diagram for this strategy is shown in the following diagram:
The Client requests the value object from the BusinessEntity. The ValueObjectFactory receives a method call from the BusinessEntity to create a new value object. The BusinessEntity will pass the ValueObject class as an argument. The ValueObjectFactory uses reflection to dynamically obtain the class information for the value object class and construct a new ValueObject instance. Getting values from and setting values into the BusinessEntity by the ValueObjectFactory is accomplished by using dynamic invocation. There is a tradeoff associated with this strategy. Its power and flexibility must be weighed against the performance overhead associated with runtime reflection. Consequences
The entity bean provides a getData() method to get the value object containing the attribute values. This may eliminate having multiple get methods implemented in the bean and defined in the bean's remote interface. Similarly, if the entity bean provides a setData() method to update the entity bean attribute values in a single method call, it may eliminate having multiple set methods implemented in the bean and defined in the bean's remote interface. The Value Object pattern transfers the values from the entity bean to the client in one remote method call. The value object acts as a data carrier and reduces the number of remote network method calls required to obtain the attribute values from the entity beans. The reduced chattiness of the application results in better network performance. Adopting the mutable value object strategy allows the client to perform modifications on the local copy of the value object. Once the modifications are completed, the client can invoke the entity's setData() method and pass the modified value object to the entity. The entity receives the modifications and merges the new (modified) values with its attributes. However, there may be a problem with stale value objects. The entity updates its values, but it is unaware of other clients that may have previously requested the same value object. These clients may be holding in their local cache value object instances that no longer reflect the current copy of the entity's data. Because the entity is not aware of these clients, it is not possible to propagate the update to the stale value objects held by other clients. The entity merges modified values into its own stored values when it receives a mutable value object from a client. However, the entity must handle the situation where two or more clients simultaneously request conflicting updates to the entity's values. Allowing such updates may result in data conflicts. Version control is one way of avoiding such conflict. As one of its attributes, the entity can include a version number or a last modified time stamp. An update transaction can resolve conflicts using the time stamp or version number attribute. If a client holding a stale value object tries to update the entity, the entity can detect the stale version number or time stamp and inform the client of this error condition. The client then has to obtain the latest value object and retry the update. Instead of multiple client calls over the network to the BusinessObject to get attribute values, this solution provides a single method call. At the same time, this one method call returns a greater amount of data to the client than the individual assessor methods each returned. When considering the Value Object pattern, you must consider the tradeoff between less network calls versus transmitting more data per call. When two or more clients concurrently access the BusinessObject, the container applies the transaction semantics of the EJB architecture. If the transaction isolation level is set to TRANSACTION_SERIALIZED, the container provides the maximum protection to the transactions and ensures its integrity. For example, suppose the workflow for the first transaction involves obtaining a value object, then subsequently modify the BusinessObject attributes in the process. The second transaction, since it is isolated to serialized transactions, will obtain the value object with the correct (most recently updated) values. However, for transactions with lesser restrictions than serialized, protection is less rigid leading to inconsistencies in the value objects obtained by competing accesses. In addition, problems explained above related to synchronization, stale value objects, and version control will have to be dealt with. Related Patterns
The session façade, which is the business interface for clients of J2EE applications, frequently uses value objects as an exchange mechanism with participating entity beans. When the façade acts as a proxy to the underlying business service, the value object obtained from the entity beans can be passed to the client. The Value Object Assembler is a pattern that builds composite value objects from different data sources. The data sources are usually session beans or entity beans that may be requested to provide their data to the ValueObjectAssembler as value objects. These value objects are considered to be parts of the composite object that the ValueObjectAssembler assembles. The Value List Handler is another pattern that provides lists of value objects constructed dynamically by accessing the persistent store at request time. The Value Object pattern address the need of getting data from BusinessObjects across tiers. This certainly is one aspect of design considerations for entity beans. The Aggregate Entity pattern discusses issues involved in designing coarse-grained entity beans. The Aggregate Entity pattern addresses complex requirements and discusses other factors and considerations involved in entity bean design.
(c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved. Version 1.0 Beta | |||
Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.
|
| ||||||||||||