Mastering Enterprise JavaBeans™ and the Java 2 Platform, Enterprise Edition - Roman E.
.pdf
J2EE in the Real World: Implementing Our E- Commerce Entity Beans 
391
*
*- The customerPK field is our Customer's Primary Key,
*and is a persistable container-managed field.
*
*- The customer field is our Customer's EJB Object.
*It is not a persistent container-managed field, but
*rather is there for convenience, so we can call
*methods on it.
*
*/
protected Customer customer; public String customerPK;
/*
* The date this order was placed. */
public java.sql.Timestamp date;
/*
* The order subtotal. */
public double subTotal;
/*
* The taxes incurred. */
public double taxes;
//------------------------------------------------------
// End Container-Managed fields //------------------------------------------------------
//------------------------------------------------------
// Begin business methods //------------------------------------------------------
public Enumeration getLineItems() throws RemoteException { OrderLineItemHome home = null;
try {
Context initCtx = new InitialContext(ctx.getEnvironment()); home = (OrderLineItemHome)
initCtx.lookup("Ecommerce.OrderLineItemHome"); return home.findByOrder(orderID);
} catch (Exception e) {
throw new ServerException("Lookup failed", e);
}
}
Source 13.10 OrderBean.java (continues).
Go back to the first page for a quick link to buy this book online!
392 
M A S T E R I N G E N T E R P R I S E J A V A B E A N S
public Customer getCustomer() throws RemoteException { return customer;
}
public double getSubtotal() throws RemoteException { return subTotal;
}
public void setSubtotal(double subTotal) throws RemoteException { this.subTotal = subTotal;
}
public double getTaxes() throws RemoteException { return taxes;
}
public void setTaxes(double taxes) throws RemoteException { this.taxes = taxes;
}
public double getTotalPrice() throws RemoteException { return subTotal - taxes;
}
public java.sql.Timestamp getDate() throws RemoteException { return date;
}
//------------------------------------------------------
// End public business methods //------------------------------------------------------
//------------------------------------------------------
//Begin EJB-Required methods. The methods below are
//called by the Container and are never called by client
//code.
//------------------------------------------------------
/**
*Associates this Bean instance with a particular context.
*Once done, we can query the Context for environment
*info, such as Bean customizations via properties.
*/
public void setEntityContext(EntityContext ctx) throws RemoteException { System.out.println("Order.setEntityContext called");
this.ctx = ctx;
}
Source 13.10 OrderBean.java (continues).
Go back to the first page for a quick link to buy this book online!
J2EE in the Real World: Implementing Our E- Commerce Entity Beans 
393
/**
*Disassociates this Bean instance with a particular
*context environment.
*/
public void unsetEntityContext() throws RemoteException { System.out.println("Order.unsetEntityContext called"); this.ctx = null;
}
/**
*Called directly after activating this bean instance.
*You should acquire needed resources in this method.
*/
public void ejbActivate() throws RemoteException { System.out.println("Order.ejbActivate() called.");
}
/**
*Called directly before passivating this bean instance.
*Release any resources you acquired in ejbActivate() in
*this method.
*/
public void ejbPassivate() throws RemoteException { System.out.println("Order.ejbPassivate () called.");
}
/**
*Updates the database to reflect the current values of
*this object.
*
*Since we're using Container-Managed Persistence, the
*Container will automatically save our public container-
*managed fields into the database. We should perform any
*necessary preprocessing here.
*/
public void ejbStore() throws RemoteException { System.out.println("Order.ejbStore() called.");
/*
*Since the container persists primary keys only,
*we must convert our references to EJB Objects
*into primary keys.
*/
customerPK = ((CustomerPK)customer.getPrimaryKey()).customerID;
}
/**
* Updates this object to reflect any changes to the
Source 13.10 OrderBean.java (continues).
Go back to the first page for a quick link to buy this book online!
394 
M A S T E R I N G E N T E R P R I S E J A V A B E A N S
*database data.
*Since we're using Container-Managed Persistence, the EJB
*Container will automatically set our public fields to
*the correct values. We then do post-processing here.
*/
public void ejbLoad() throws RemoteException { System.out.println("Order.ejbLoad() called.");
/*
*Since the container persists primary keys only,
*we must convert the loaded primary key info for
*our Customer into an EJB Object.
*/ try {
/*
*Form JNDI initial context.
*Note: We rely on the environment properties
*that the bean was deployed with for any
*necessary initialization parameters.
*/
Context initCtx = new InitialContext(ctx.getEnvironment());
/*
* Lookup home object via JNDI */
CustomerHome home = (CustomerHome) initCtx.lookup("Ecommerce.CustomerHome");
/*
* Find the EJB Object based on its primary key */
customer = home.findByPrimaryKey(new CustomerPK(customerPK));
}
catch (Exception e) {
throw new RemoteException(e.toString());
}
}
/**
*Called when new database data is created.
*When the client calls the Home Object's create() method,
*the Home Object then calls this ejbCreate() method.
*
*We need to initialize our Bean's container-managed
*fields with the parameters passed from the client, so
*that the Container can inspect our Bean and create the
Source 13.10 OrderBean.java (continues).
Go back to the first page for a quick link to buy this book online!
J2EE in the Real World: Implementing Our E- Commerce Entity Beans 
395
* corresponding database entries. */
public void ejbCreate(String orderID, Customer c) throws CreateException, RemoteException {
System.out.println("Order.ejbCreate(" + orderID + ") called");
this.orderID = orderID;
this.customer = c;
this.customerPK = ((CustomerPK)customer.getPrimaryKey()).customerID;
this.date = new java.sql.Timestamp(System.currentTimeMillis()); this.subTotal = 0;
this.taxes = 0;
}
/**
*The Container calls this after ejbCreate(). At this
*point in time, the bean instance is associated with its
*own EJB Object. You can get a reference to that
*EJB Object by querying the context. You'd use that
*EJB Object reference when calling an external module,
*and you'd like to pass a reference to yourself.
*/
public void ejbPostCreate(String orderLineItemID, Customer c) throws CreateException, RemoteException { System.out.println("Order.ejbPostCreate() called");
}
/**
*Called before the container removes entity bean data
*from the database. Corresponds to when client calls
*home.remove().
*/
public void ejbRemove() throws RemoteException, RemoveException { System.out.println("Order.ejbRemove() called.");
Enumeration e = getLineItems(); while (e.hasMoreElements()) {
OrderLineItem li = (OrderLineItem) e.nextElement(); li.remove();
}
}
// No finder methods - they are implemented by Container
//------------------------------------------------------
// End EJB required methods //------------------------------------------------------
}
Source 13.10 OrderBean.java (continued).
Go back to the first page for a quick link to buy this book online!
396 
M A S T E R I N G E N T E R P R I S E J A V A B E A N S
OrderHome.java
Our home interface is used to create new Orders and find existing Orders. The code is in OrderHome.java, presented in Source 13.11.
In addition to a create() and findByPrimaryKey() method, our entity bean defines several custom finder methods. This will give clients several useful ways to find existing Orders.
package com.wiley.compBooks.ecommerce;
import javax.ejb.*;
import java.rmi.RemoteException; import java.util.Enumeration; import java.util.Date;
/**
*This is the home interface for Order. This interface
*is implemented by the EJB Server's glue-code tools -
*the implemented object is called the Home Object and
*serves as a factory for EJB Objects.
*
*One create() method is in this Home Interface, which
*corresponds to the ejbCreate() method in the Order file. */
public interface OrderHome extends EJBHome {
/*
*This method creates the EJB Object.
*Notice that the Home Interface returns an
*EJB Object, whereas the Bean returns void.
*This is because the EJB Container is responsible
*for generating the EJB Object, whereas the Bean
*is responsible for initialization.
*
*@param orderID The unique ID of this order
*@param c The customer who owns this order
*@return The newly created EJB Object.
*/
public Order create(String orderID, Customer c) throws CreateException, RemoteException;
//Finder methods, implemented by Container due to
//Container-Managed Persistence
Source 13.11 OrderHome.java (continues).
Go back to the first page for a quick link to buy this book online!
J2EE in the Real World: Implementing Our E- Commerce Entity Beans 
397
public Order findByPrimaryKey(OrderPK key) throws FinderException, RemoteException;
public Enumeration findByCustomerKey(CustomerPK key) throws FinderException, RemoteException;
public Enumeration findByDate(java.sql.Timestamp date) throws FinderException, RemoteException;
public Enumeration findAllOrders() throws FinderException, RemoteException;
}
Source 13.11 OrderHome.java (continued).
OrderPK.java
Our primary key class, OrderPK.java, is straightforward. It exposes the Order ID as the single primary key field. The code is shown in Source 13.12.
package com.wiley.compBooks.ecommerce;
import java.io.Serializable;
/**
*Primary Key class for our Order Container-
*Managed Persistent Entity Bean
*/
public class OrderPK implements java.io.Serializable {
/*
*Note that the primary key fields must be a subset of
*the container-managed Bean fields.
*/
public String orderID;
public OrderPK(String orderID) { this.orderID = orderID;
}
public OrderPK() {
}
public String toString() { return orderID.toString();
}
Source 13.12 OrderPK.java (continues).
Go back to the first page for a quick link to buy this book online!
398 
M A S T E R I N G E N T E R P R I S E J A V A B E A N S
public int hashCode()
{
return orderID.hashCode();
}
public boolean equals(Object order)
{
return ((OrderPK)order).orderID.equals(orderID);
}
}
Source 13.12 OrderPK.java (continued).
OrderException.java
Finally, we define a custom exception class, OrderException.java. These exceptions are thrown from several of our bean’s methods. The code is displayed in Source 13.13.
The Deployment Descriptor
We present our Order entity bean’s deployment descriptor in Table 13.8.
package com.wiley.compBooks.ecommerce;
/**
* Exceptions thrown by Order */
public class OrderException extends Exception {
public OrderException() { super();
}
public OrderException(Exception e) { super(e.toString());
}
public OrderException(String s) { super(s);
}
}
Source 13.13 OrderException.java.
Go back to the first page for a quick link to buy this book online!
J2EE in the Real World: Implementing Our E- Commerce Entity Beans 
399
Table 13.8 Deployment Descriptor Settings for Order Bean
DEPLOYMENT
DESCRIPTOR SETTING |
VALUE |
Bean home name |
Ecommerce.OrderHome |
Enterprise bean class name |
com.wiley.compBooks.ecommerce.OrderBean |
Home interface class name |
com.wiley.compBooks.ecommerce.OrderHome |
Remote interface class name |
com.wiley.compBooks.ecommerce.Order |
Environment properties |
see Table 13.11 |
Re-entrant |
false |
Primary key class name |
com.wiley.compBooks.ecommerce.OrderPK |
Container-managed fields |
orderID, customerPK, lineItemPKs, date, subTotal, and |
|
taxes |
Transaction isolation level |
TRANSACTION_SERIALIZABLE |
Transaction attribute |
TX_REQUIRED |
Run-as mode |
CLIENT_IDENTITY |
|
|
As with order line items, orders represent mission-critical data that must be preserved in a multiuser situation. We use the TRANSACTION_SERIALIZABLE isolation level to enforce this.
Next, we define a mapping for our container-managed fields to an underlying data store—currently a step that varies for each container. The field mapping is shown for the BEA WebLogic container in Table 13.9.
Table 13.9 Persistent Settings for Our Order Bean Assuming the BEA WebLogic Container
OBJECT/RELATIONAL SETTING
(ENTITY BEAN FIELD = RELATIONAL COLUMN NAME)
orderID =id
customerPK=customerPK
lineItemPKs=lineItemPKs
date=orderDate
subTotal=orderSubTotal
taxes=orderTaxes
Go back to the first page for a quick link to buy this book online!
400 
M A S T E R I N G E N T E R P R I S E J A V A B E A N S
Table 13.10 Finder Semantics for Order Bean Assuming the BEA WebLogic Container
FINDER SCRIPTING SYNTAX
“findByCustomerKey(com.wiley.compBooks.ecommerce.CustomerPK key)” “(= customerPK $key)”
“findByDate(java.util.Date date)” “(= date $date)”
“findAllOrders()” “(= 1 1)”
Table 13.11 Environment Properties for OrderLineItemBean
ENVIRONMENT PROPERTY SETTING |
VALUE |
java.naming.factory.initial |
“weblogic.jndi.TengahInitialContextFactory” |
java.naming.provider.url |
“t3://localhost:7001” |
We also enumerate the logic of the finder methods that the container should implement. Again, this is also EJB container–specific, and it is shown for the BEA WebLogic container in Table 13.10.
We also use a number of environment properties. They are shown in Table 13.11. As with our Order Line Items, these environment property settings are necessary for JNDI initialization in our bean’s ejbLoad() method, when transforming primary keys into EJB objects.
Summary
This concludes our e-commerce deployment’s entity beans. You’ve now been exposed to some of the hairy issues that arise when performing a real deployment with EJB, such as how to use multiple entity beans together and dealing with the limitations of entity bean relationships.
We continue with our EJB coding in the next chapter, defining our business logic session beans. This includes a Quote bean acting as a shopping cart, a Quote Line Item bean, a Pricing engine bean, and a Bank Teller bean.
Go back to the first page for a quick link to buy this book online!
