- What is UML?
- What Are Entity Beans?
- State/Capital City Example
- Customer/Orders Example
- Conclusion
Customer/Orders Example
Now that we've covered a simple example that maps a UML class diagram to CMP entity bean implementation code, let's look at a more involved example. Figure 2 shows a class diagram modeling entities customer (Customer EJB), orders (Order EJB), and line items (LineItem EJB).
Figure 2 Customer EJB, Order EJB, and LineItem EJB class diagram.
Persistent Fields
Customer EJB has several attributes, including a name and an email address, that map to corresponding persistent fields. Likewise, Order EJB has attributes that include a total amount (a double) and an order status (an integer). Let's look at a portion of the bean implementation code for Customer EJB, showing the mapping for attributes name and email, as well as the implied primary key:
public abstract class CustomerBean implements EntityBean { // Access methods for primary key public abstract String getCustomerID(); public abstract void setCustomerID(String id); // Access methods for attributes public abstract String getName(); public abstract void setName(String name); public abstract String getEmail(); public abstract void setEmail(String email); . . . }
Remember, both the class and the methods are abstract because the application server generates the implementation code for these methods. Here is a portion of the bean implementation code for Order EJB:
public abstract class OrderBean implements EntityBean { // Access methods for primary key public abstract String getOrderID(); public abstract void setOrderID(String id); // Access methods for attributes public abstract double getTotalAmount(); public abstract void setTotalAmount(double amount); public abstract int getOrderStatus(); public abstract void setOrderStatus(int status); . . . }
Relationships
What sorts of relationships does the class diagram in Figure 2 show? You'll note that a customer may have more than one order associated with it. The notation 0..* means many, where many may be zero or more. This means that it is perfectly okay for a customer to have no orders or to have multiple orders. When a relationship allows many, we use a Java collection (java.util.Collection) for the relationship type. Here is a portion of the bean implementation code for Customer EJB that shows the mapping for the relationship with Order EJB:
public abstract class CustomerBean implements EntityBean { . . . // Access methods for relationship fields public abstract Collection getOrders(); public abstract void setOrders(Collection orders); . . . }
Now let's look at the Order EJB. First, an order must have exactly one customer. (This is mandatory, meaning that an order must have an associated customer at all times.) What is the multiplicity between an order and a line item? An order has many line items, where many is one or more (1..*), and a line item has exactly one order. One or more means mandatory, which indicates that an order must have at least one line item at all times (zero is not allowed). Similarly, a line item must always have one associated order. As you learned earlier, mandatory means that these relationships are initialized during the creation process. Here is a portion of the bean implementation code for Order EJB that shows the mapping for the order relationship with a customer and a line item:
public abstract class OrderBean implements EntityBean { . . . // Access methods for relationship fields public abstract CustomerLocal getCustomer(); public abstract void setCustomer(CustomerLocal customer); public abstract Collection getLineItems(); public abstract void setLineItems(Collection lineItems); . . . }
Note that we use the local interface object (CustomerLocal) for the singular customer relationship and java.util.Collection for the many line item relationship.
Relationship Life Cycle Issues
Because the relationship between customer and order is one to many (where many is zero or more), a Customer EJB does not necessarily have an associated order. This means that the relationship cannot be initialized during Customer EJB's create process. However, because an order must have an associated customer, the initialization does occur during Order EJB's creation process. Let's see how this is done in Listing 5 with the ejbCreate() and ejbPostCreate() methods for Order EJB.
Listing 5: Order EJB Implementation Methods ejbCreate() and ejbPostCreate()
public abstract class OrderBean implements EntityBean { . . . public String ejbCreate(double totalAmount, int orderStatus, long orderDate, long shipDate, CustomerLocal customer) throws CreateException { String newKey = DBUtil.dbGetKey(); // initialize all persistent fields setOrderID(newKey); setTotalAmount(totalAmount); setOrderStatus(orderStatus); setOrderDate(orderDate); setShipDate(shipDate); return newKey; } public void ejbPostCreate(double totalAmount, int orderStatus, long orderDate, long shipDate, CustomerLocal customer) { // initialize relationship with customer setCustomer(customer); } . . . }
Note that ejbCreate()'s arguments match those of ejbPostCreate(). As before, we generate the primary key internally. In ejbPostCreate(), we initialize the relationship with Customer EJB. The container takes care of initializing the other end of the relationship.
Where is the relationship between order and line item initialized? Because this relationship is mandatory in both directions, we must choose one side and provide the initialization in ejbPostCreate(). For order and line item, initialization occurs in LineItem EJB, as shown in Listing 6.
Listing 6: LineItem EJB Implementation Methods ejbCreate() and ejbPostCreate()
public abstract class LineItemBean implements EntityBean { . . . public String ejbCreate(String title, int quantity, OrderLocal order) throws CreateException { String newKey = DBUtil.dbGetKey(); setLineItemID(newKey); setTitle(title); setQuantity(quantity); return newKey; } public void ejbPostCreate(String title, int quantity, OrderLocal order) { // associate this LineItem EJB with Order EJB setOrder(order); } . . . }
Mapping Declarative Information
Our customer/order example has two associations (customer/orders and order/line items). From the information in our class diagram, we can specify declarative information. Listing 7 provides the deployment descriptor tags that describe the relationship between Customer EJB and Order EJB. This relationship is one to many, and cascading deletes apply to Order EJB (if we delete a customer, its associated orders must also be deleted because an order cannot exist without a customer). Note that the CMR field named orders is type java.util.Collection (because it is many).
Listing 7: XML Tags Describing the Relationship Between Customer EJB and Order EJB
<relationships> <ejb-relation> <ejb-relation-name></ejb-relation-name> <ejb-relationship-role> <ejb-relationship-role-name>CustomerBean</ejb-relationship-role-name> <multiplicity>One</multiplicity> <relationship-role-source> <ejb-name>CustomerBean</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>orders</cmr-field-name> <cmr-field-type>java.util.Collection</cmr-field-type> </cmr-field> </ejb-relationship-role> <ejb-relationship-role> <ejb-relationship-role-name>OrderBean</ejb-relationship-role-name> <multiplicity>Many</multiplicity> <cascade-delete /> <relationship-role-source> <ejb-name>OrderBean</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>customer</cmr-field-name> </cmr-field> </ejb-relationship-role> </ejb-relation>
Listing 8 gives the deployment descriptor tags that describe the relationship between Order EJB and LineItem EJB. This relationship is one to many, and cascading deletes apply to LineItem EJB (if we delete an order, its associated line items must also be deleted). The CMR field named lineItems is type java.util.Collection.
Listing 8: XML Tags Describing the Relationship Between Order EJB and LineItem EJB
<ejb-relation> <ejb-relation-name></ejb-relation-name> <ejb-relationship-role> <ejb-relationship-role-name>OrderBean</ejb-relationship-role-name> <multiplicity>One</multiplicity> <relationship-role-source> <ejb-name>OrderBean</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>lineItems</cmr-field-name> <cmr-field-type>java.util.Collection</cmr-field-type> </cmr-field> </ejb-relationship-role> <ejb-relationship-role> <ejb-relationship-role-name>LineItemBean</ejb-relationship-role-name> <multiplicity>Many</multiplicity> <cascade-delete /> <relationship-role-source> <ejb-name>LineItemBean</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>order</cmr-field-name> </cmr-field> </ejb-relationship-role> </ejb-relation> </relationships>