Aggregate Entity
Entity beans are not intended to represent every persistent object in the object model. Entity beans are better suited for coarse-grained persistent business objects.
In a J2EE application, clients (applications, JavaServer Pages, Servlets,
JavaBeansTM technologies) access entity beans via their remote
interfaces. Thus, every client invocation potentially routes through network stubs and skeletons
even if the client and the enterprise bean are in the same JavaTM
virtual machine, OS, or machine. When entity beans are fine-grained objects, clients tend to invoke
more individual entity bean methods, resulting in high network overhead.
Entity beans represent distributed persistent business objects. Whether developing or migrating an application to the J2EE platform, object granularity is very important when deciding what to implement as an entity bean. Entity beans should represent coarse-grained business objects, such as those that provide complex behavior beyond simply getting and setting field values. These coarse-grained objects typically have dependent objects, which are objects that have no real domain meaning when not associated with its coarse-grained parent.
A recurring problem is the direct mapping of the object model to an EJBTM model (specifically entity beans). This creates a relationship between the entity bean objects without consideration of coarse-grained vs. fine-grained (or dependent) objects. Determining what to make coarse-grained vs. fine grained is typically difficult and can best be done via modeling relationships in UML models.
The drawback with creating a deep entity bean to entity bean relationship for one thing is the overhead associated with the relationship communication. Also, regardless of the container in which they reside, entity bean-to-entity bean method invocations are treated as remote calls traversing the network layer, and are thus subject to the same network overhead as client-to-entity bean method invocations.
There are a number of areas impacted by the fine-grained entity bean design approach:
- Impact on relationships
Direct mapping of an object model directly to an EJB model does not take into account the impact of relationships between the objects. The inter-object relationships are directly transformed into inter-entity bean relationships. As a result, an entity bean might contain a reference to another entity bean (that is, the entity bean holds a remote reference to another entity bean). However, maintaining remote references to distributed objects involves different techniques and semantics than maintaining references to local objects. Besides increasing the complexity of the code, it reduces the flexibility because the entity bean must change if there are any changes in its relationships.
There is also no guarantee that the entity bean references to other entity beans remain valid over time. Such references are established dynamically using the entity's home object and the primary key for that entity bean instance. This implies a high maintenance overhead of reference validity checking for each such entity bean-to-entity bean reference.
- Impact on Manageability
Implementing fine-grained objects as entity beans results in a large number of entity beans in the system. An entity bean is associated with several classes. For each entity bean component, the developer must provide classes for the home interface, the remote interface, the bean implementation and the primary key.
In addition, the container may generate additional classes to support the entity bean implementation. When the bean is created, these classes are realized as real objects in the container. In short, the container creates a number of objects to support each entity bean instance. Large number of entity beans results in more classes and code to maintain for the development team. It also results in a large number of objects in the container. This can negatively impact the application performance.
- Network Performance
With the fine-grained entity beans, there are inter-entity bean relationships. Because entity beans are distributed in nature, even if one entity bean invokes a method on another entity bean, the call is potentially treated as a remote call by the container even if both the entity beans are in the same container or JVM. If the number of entity bean-to-entity bean relationships increases, then this negatively impacts system scalability due to heavy network overhead.
- Database Schema Dependency
When the entity beans are fine-grained, each entity bean instance usually represents a single row in a database. This is not a proper application of the entity bean design since entity beans are more suitable for coarse-grained components. Fine-grained entity bean implementation typically is a direct representation of the underlying database schema in the entity bean design. When clients use these fine-grained entity beans, they are operating at the row level in the database since each entity bean is effectively a single row. Thus the clients become dependent on the database schema, since they are effectively using the database row as is with an entity bean. When the schema changes, the entity bean definitions change as well. Further, since the clients are operating at the same granularity, they must observe and react to this change. This schema dependency causes a loss of flexibility and increases the maintenance overhead whenever schema changes are required.
- Impact of Object Granularity (Coarse-grained versus. Fine-grained)
Object granularity impacts data transfer between the enterprise bean and the client. In most applications, clients typically need a larger chunk of data than one or two rows from a table. In such a case, implementing each of these fine-grained objects as an entity bean means that the client would have to manage the relationships between all these fine-grained objects. Depending on the data requirements, the client might have to perform many lookups of a number of entity beans to obtain the required information.
- Entity beans are best implemented as coarse-grained objects due to the high overhead associated with each entity bean. Each entity bean is associated with an EJB home, remote object, bean implementation, and primary key, and each is managed by the container services.
- Applications that directly map relational database schema to entity beans (where each row in a
table is represented by an entity bean instance) tend to have a large number of fine-grained entity
beans. It is desirable to keep the entity beans coarse-grained and reduce the number of entity beans
in the application.
- Direct mapping of object model to EJB model yields fine-grained entity beans. Fine-grained
entity beans usually map to the database schema. This entity to database row mapping causes problems
related to performance, manageability, security, and transaction handling. Relationships between
tables are implemented as relationships between entity beans, which means that entity beans hold
references to other entity beans to implement the fine-grained relationships. It is very expensive
to manage inter-entity bean relationships because these relationships must be established dynamically
using the entity home objects and the enterprise beans' primary keys.
- Clients do not need to know the implementation of the database schema to use and support the entity beans. With fine-grained entity beans, the mapping is usually done such that each entity bean instance maps to a single row in the database. This fine-grained mapping creates a dependency between the client and the underlying database schema since the clients deal with the fine-grained beans and they are essentially a direct representation of the underlying schema. This results in tight coupling between the database schema and entity beans. A change to the schema causes a corresponding change to the entity bean, and, in addition, requires a corresponding change to the clients.
- There is an increase in chattiness of applications due to inter-communication among fine-grained entity beans. Excessive inter-entity bean communication often leads to a performance bottleneck. Every method call to the entity bean is made via the network layer, even if the caller is in the same address space as the called bean (that is, both the client/entity bean and the called entity bean are in the same container). While some container vendors optimize for this scenario, the developer cannot rely on this optimization in all containers.
- Additional chattiness can be observed between the client and the entity beans because the client may have to communicate with many fine-grained entity beans to fulfill a requirement. It is desirable to reduce the communication between or among entity beans and to reduce the chattiness between the client and the entity bean layer.
Use Aggregate Entity bean to model, represent, and manage a set of inter-related persistent objects rather than representing them as individual fine-grained entity beans. An Aggregate Entity bean represents a tree of objects.
To understand aggregation in the context of this pattern, one must first understand persistent objects and their relationships in an application. A persistent object is an object that is stored in some type of data store. Multiple clients usually share persistent objects.
Persistent objects can be classified into two types: coarse-grained objects and dependent objects.
A coarse-grained object is self-sufficient. It has its own life cycle and manages its relationships to other objects. Each coarse-grained object may reference or contain one or more other objects. The coarse-grained object usually manages the life cycles of these objects. Hence, these objects are called dependent objects. A dependent object can be a simple self-contained object or may in turn contain other dependent objects.
The life cycle of a dependent object is tightly coupled to the life cycle of the coarse-grained object. A client may only indirectly access a dependent object through the coarse-grained object. That is, dependent objects are not directly exposed to clients because their parent (coarse-grained) object manages them. Dependent objects cannot exist by themselves. Instead, they always need to have their coarse-grained (or parent) object to justify their existence.
Typically, you can view the relationship between a coarse-grained object and its dependent objects as a tree. The coarse-grained object is the root of the tree (the root node). Each dependent object can be a standalone dependent object (a leaf node) that is a child of the coarse-grained object. Or, the dependent object can have parent-child relationships with other dependent objects, in which case it is considered a branch node.
An Aggregate Entity bean can represent a coarse-grained object and all its related dependent objects. Aggregation combines inter-related persistent objects into a single entity bean, thus drastically reducing the number of entity beans required by the application. This leads to a highly coarse-grained entity bean that can better leverage the benefits of entity beans than fine-grained entity beans.
Without the Aggregate Entity approach, there is a tendency to view each coarse-grained and dependent object as a separate entity bean, leading to a large number of entity beans.
While there are many strategies in implementing the Aggregate Entity pattern, the first one we discuss is represented in the following class diagram. Here the Aggregate Entity contains the coarse-grained object, and the coarse-grained object contains dependent objects.

The diagram below shows the interactions for this pattern:

click to enlarge
AggregateEntity
AggregateEntity is the coarse-grained entity bean. The AggregateEntity may be either the coarse-grained object or it may hold a reference to the coarse-grained object. The Strategies section explains the different implementation strategies for an Aggregate Entity.
CoarseGrained Object
A coarse-grained object is an object that has its own life cycle and manages its own relationships to other objects. A coarse-grained object can be a Java object contained in the Aggregate Entity. Or, the Aggregate Entity itself can be the coarse-grained object that holds dependent objects. These strategies are explained in the Strategies section.
DependentObject1, DependentObject2 & DependentObject3
A dependent object is an object that depends on the coarse-grained object and has its life cycle managed by the Coarse-grained Object. A dependent object can contain other dependent objects; thus there may be a tree of objects within the Aggregate Entity.
|
Dependent or Coarse-grained: What are they?
According to the EJB 2.0 specification, a dependent object is defined as follows:
"A dependent object class is a persistent helper class that is used by one or more entity beans to further model their persistent state. A dependent object is used internally by an entity bean and is itself not directly exposed through the client view."
In another section of the specification, this definition is formalized as follows:
"A dependent object can be characterized as follows. An object D is a dependent object, if D is created by another object, if D can only be accessed through another object (and not remotely), and if D's existence or removal is dependent on some other object: in other words, if D's life cycle is managed by some other object."
So, what do we call the "other" object that manages the life cycle of dependent objects? Our pattern calls it the "coarse-grained" object, and emphasizes the relationship between the entity bean and the dependent objects. The first specification definition defines the object that holds the dependent object as the entity bean. The second definition provides a different view of the relationships. We can view the dependent objects as a tree of objects with a root object at the top. The object that is the root of the tree is the "coarse-grained" object responsible for the life cycle of the tree.
We present different strategies that explain how the coarse-grained object relates to the entity bean design. In one strategy, Entity Contains the Coarse-grained Object, the entity bean holds a reference to the node (coarse-grained object) of the tree as a member. In another strategy, Entity Implements the Coarse-grained Object, the entity bean itself is the node of the tree, that is, the coarse-grained object.
Keep in mind that the description of the similarity of the dependent objects is restricted to the above definition. However, the EJB 2.0 specification provides more features associated with dependent objects that are not relevant to this pattern. This pattern applies to EJB 1.1 as well as EJB 2.0 since the emphasis is on the design of Aggregate Entity beans. |
This section explains different strategies for implementing an Aggregate Entity. The strategies consider possible alternatives and options for persistent objects (coarse-grained and dependent) and the use of value objects.
In this strategy, the Aggregate Entity holds or contains the coarse-grained object. The coarse-grained object continues to have relationships with its dependent objects. The structure section of this pattern describes this strategy.
In this strategy, the Aggregate Entity itself is the coarse-grained object and it has the coarse-grained object's attributes and methods. The dependent objects are attributes of the Aggregate Entity. Since the Aggregate Entity is the coarse-grained object, the entity bean expresses and manages all relationships between the coarse-grained object and the dependent objects.
The following is the class diagram for this strategy:

The sequence diagram for this strategy is shown below:

An Aggregate Entity can be composed of many levels of dependent objects in its tree of objects. Loading all the dependent objects when the Aggregate Entity's ejbLoad() method is called by the EJB Container may take considerable time and resources. One way to optimize this is by using a lazy loading strategy for loading the dependent objects. When the ejbLoad() method is called, at first only load those dependent objects that are most crucial to the Aggregate Entity clients. Subsequently, when the clients access a dependent object that has not yet been loaded from the database, the Aggregate Entity can perform a load on demand. Thus, if some dependent objects are not used, they are not loaded on initialization. However, when the clients subsequently need those dependent objects, they get loaded at that time.
A common problem with bean managed persistence occurs when persisting the complete object graph during an ejbStore() operation. Since the EJB Container has no way of knowing what data has changed in the entity bean and its dependent objects, it puts the burden on the developer to determine what and how to persist the data. Some EJB containers provide feature to identify what objects in Aggregate Entity's graph need to be stored due to a prior update. This may be done by having the developers implement a special method in the dependent objects (for example, isDirty()) that is called by the container to check if the object has been updated since the previous ejbStore() operation.
A generic solution may be to use an interface DirtyMark as shown in the following class diagram. The idea is to have dependent objects implement the DirtyMark interface to let the caller (typically ejbStore() method) know if the state of the dependent object has changed. This way the caller can choose to obtain the data for subsequent storage.

The following sequence diagram shows an example interaction for this strategy.

click to enlarge
The client performs an update to the Aggregate Entity, which results in a change to DependentObject3. DependentObject3 is accessed via its parent DependentObject2. The Aggregate Entity is the parent of DependentObject2. When this update is performed, the setDirty() method is invoked in the DependentObject3. Subsequently, when the container invokes the ejbStore() method on this Aggregate Entity instance, the ejbStore() method can check which dependent objects have gone dirty and selectively save those changes to the database. The dirty marks are reset once the store is successful.
In cases where ejbStore() is invoked with no intermediate updates to the Aggregate Entity, none of the dependent objects have been
This strategy avoids the huge overhead of having to persist the entire dependent objects graph to the database whenever the ejbStore() method is invoked by the container.
|
Note:
The Lazy Loading Strategy and the Store Optimization Strategy are being addressed by the EJB 2.0 specification which is in final draft at the time of this writing. However, it is possible to use these strategies in pre-EJB 2.0 implementations. Please follow the EJB 2.0 developments to understand how these strategies will be finalized in the specification. |
Aggregate (Composite) Value Object Strategy
With an Aggregate Entity, a client can obtain all required information with just one remote method call. Because the Aggregate Entity either implements or holds the coarse-grained object and the hierarchy (or tree) of dependent objects, it can create the required value object and return it to the client.

click to enlarge
The value object can be a simple object or a composite (aggregate) object that has sub-objects (tree structure), depending on the data requested by the client. The value object is serializable and it is passed by value to the client. The value object functions only as a data transfer object; it has no responsibility with respect to security, transaction, and business logic. The value object packages all information into one object, obtaining the information with one remote call rather than multiple remote calls. Once the client receives the value object, all further calls from the client to the value object are local to the client.
- Relationships
Using the Aggregate Entity pattern, the dependent objects are aggregated in to a single entity bean eliminating all inter-entity bean relationships. This pattern provides a central place to manage both relationships and object hierarchy.
- Manageability
As you can see, implementing persistent objects as fine-grained entity beans results in a large number of classes that need to be developed and maintained. Using an Aggregate Entity reduces the number of EJB classes and code and makes maintenance easier. It improves the manageability of the application by having fewer coarse-grained components instead of than many more fine-grained ones.
- Network Performance
Due to the aggregation of the dependent objects . This eliminates all fine-grained communications between dependent objects across the network. If each dependent object were designed as a fine-grained entity bean, it would result in a huge network overhead due to inter-entity bean communications.
- Database Schema Dependency
When the Aggregate Entity pattern is used, it results in coarse-grained entity bean implementations. The database schema is hidden from the clients since the mapping of the entity bean and the schema is internal to the coarse-grained entity bean. Changes to the database schema may require changes to the Aggregate Entity beans. However, the clients are not affected since the Aggregate Entity beans do not expose the schema to the external world.
- Object Granularity (Coarse-grained vs. Fine Grained)
With an Aggregate Entity, the client typically looks up a single entity bean instead of a large number of fine-grained entity beans. The client requests the Aggregate Entity for data. The Aggregate Entity can create a composite value object that contains all the data from the entity bean and return the value object to the client in a single remote method call. This reduces the chattiness between the client and the EJB layers.
- Creating a Composite Value Object
By using this strategy, chattiness of the communication between the client and the entity bean is reduced since the Aggregate Entity bean can return a composite value object by providing a mechanism to send serialized value objects from the Aggregate Entity bean. Although a value object returns all data in one remote call, keep in mind that the amount of data returned with this one call is much larger than the amount of data returned by separate remote calls to obtain individual entity bean properties. This tradeoff works well when the goal is to avoid repeated remote calls and multiple lookups.
- Value Object Pattern [SJC]
The Aggregate Entity pattern uses the Value Object pattern for creating the value object and returning it to the client. The Value Object pattern is used to serialize the coarse-grained and dependent objects tree or part of the tree as required.
- Session Façade [SJC]
If dependent objects tend to be entity beans rather than the arbitrary Java objects, try to use the Session Facade pattern to manage the inter-entity bean relationships.
- Value Object Assembler [SJC]
When it comes to obtaining a composite aggregate value object from the Aggregate Entity (see the "Creating Composite Value Object" strategy above), this pattern is similar to the Value Object Assembler pattern. However, in this case, the data source for all the value objects in the composite are parts of the Aggregate Entity itself. Where as for the Value Object Assembler, the data sources are different entity beans, session beans, arbitrary Java objects, and so on.
|
Dependent Object is an enterprise bean? Issues and Recommendations
Typically, we design dependent objects as Java objects that have a direct relationship with the parent coarse-grained object. However, there may be situations when a dependent object may appear as an entity bean in itself. This can happen:
- if the dependent object appears to be depending on two different parent objects (as is the case with association classes).
- if the dependent object already exists as an entity bean in the same application or it is imported from a different application.
In these cases, the life cycle of the dependent object may not appear to be directly related to and managed by a single (parent) coarse-grained object. So, what do you do when a dependent object is an entity bean; or when you see a dependent object that is not totally dependent on its parent object; or when you cannot identify its sole parent object?
Lets consider each case in a little more detail.
1. When the dependent object depends on two parent objects:
Let us explore this with the following example. A commitment represents an association between a Resource and the Project.

Commitment is a dependent object. Both Projects and Resources are coarse-grained objects. Each Project has a 1-many relationship with Commitment objects. Each Resource has 1-many relationship Commitment objects. So, is Commitment a dependent object of Project or of Resource? The answer lies in analyzing the interactions for the use cases that involve these three objects. If you make the Commitment as a dependent of the Project, then when the Resource accesses its list Commitment objects, it has to do so through the Project object. On the other hand, if the Commitment is a dependent of a Resource, when the Project accesses its list of Commitment objects, it has to do so via the Resource. Both these choices will introduce entity-to-entity bean relationship.
But, what if the Commitment is made an entity bean instead of a dependent object? Then the relationships between the Project and its list of Commitment objects, and between a Resource and its list of Commitment objects will be an entity-to-entity bean relationships. This just worsens the problem in that now there are two entity-to-entity bean relationships.
Entity-to-entity bean relationships are not recommended due to the overhead associated with managing and sustaining such a relationship.
2. When the dependent object pre-exists as an entity bean:
In this case, it may seem that one way to model this relationship is to store the dependent object entity bean's primary key in the coarse grained object. When the coarse-grained object needs to access the dependent object, it will result in an entity-to-entity invocation.

The sequence diagram for scenario is shown below. The Aggregate Entity uses the dependent object references to look up the required dependent entity beans. The dependent object in this case is a proxy to the dependent entity bean as shown.

click to enlarge
While this may address the requirement of using a dependent entity bean from a parent entity bean, it is not an elegant solution. Instead, to avoid the complexity of designing and managing inter-entity relationships, consider using a session bean to help manage the relationships among entity beans. In our experience, we have found that the session façade pattern helps us to avoid this problem and to provide a better way of managing entity bean to entity bean relationships.
So, we recommend, that as a best practice, try and avoid entity-to-entity bean relationships. |
(c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
Version 1.0 Beta
|