Before integrating the Customer EJB into our Music Collection application, let's test it with an independent Java test client. The test client also helps show the role that the EJB container plays in managing entity beans. We've loaded several test records into our Customers database table (by accessing the database directly). Table 6.3 shows the initial test data.
Customer ID | Name | Password | Orders Pending | |
---|---|---|---|---|
101 | Catherine | Password101 | [email protected] | false |
102 | Maheu | Password102 | [email protected] | true |
103 | Cecile | Password103 | [email protected] | false |
104 | Chaval | Password104 | [email protected] | true |
105 | Levaque | Password105 | [email protected] | true |
Listing 6.15 shows the source for our test program contained in file CustomerTestClient.java. Because this is a stand-alone Java client, we access our Customer EJB through the remote interface.
We first perform the JNDI lookup associated with the EJB coded name “ejbMyCustomer” and use the PortableRemoteObject class to obtain an object that implements the home interface. We then create a new Customer record (using the name “Lydia”). Because Customer EJB generates the primary key, we can run this program more than once without duplicating primary keys, creating a distinct “Lydia” customer each time. Our CustomerSession EJB will disallow customers sharing the same name. However, we by-pass this restriction here since the test client accesses the Customer EJB directly.
Next, we call findByPrimaryKey() with customerID 101 and obtain an object that implements the remote interface (Customer). Now we can invoke business methods. After changing the password, we access the customer name. We then call findAll() to display information about each record in the database. The last call to home method getTotalCustomers() displays the total number of records. (Note that we can also determine the number of records by accessing the size() method of the collection returned by findAll().)
// CustomerTestClient.java import java.util.*; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import javax.ejb.CreateException; public class CustomerTestClient { public static void main(String[] args) { try { Context initial = new InitialContext(); Object objref = initial.lookup("java:comp/env/ejb/MyCustomer"); // Get a home interface object System.out.println("get a home interface object"); CustomerHome home = (CustomerHome)PortableRemoteObject.narrow(objref, CustomerHome.class); // Create Customer entity bean. Customer lydia = home.create("Lydia", "Lydiapassword", "[email protected]"); // Call findByPrimaryKey for PK 101 // This instantiates a different Customer EJB. Customer findPK = home.findByPrimaryKey("101"); // Call a business method for Customer object // just returned // Must update the database System.out.println("Call setPassword()"); findPK.setPassword("New Password"); // Now call a second business method // using the same Customer object System.out.println( "Call getName()"); String name = findPK.getName(); System.out.println("name = " + name); // Call finder method findAll() // and display information about // each Customer Collection c = home.findAll(); Iterator i = c.iterator(); while (i.hasNext()) { Customer cust = (Customer)i.next(); System.out.println(cust.getName() + ": " + cust.getPassword()); } // home method System.out.println(home.getTotalCustomers() + " customers in database."); } catch (CreateException ex) { System.err.println("Error creating object." ); System.err.println(ex.getMessage()); } catch (Exception ex) { System.err.println( "Caught an unexpected exception." ); System.err.println(ex.getMessage()); } finally { System.exit(0); } } } // CustomerTestClient |
Let's run this client and show you the output from both the server and the client program (mixed together to show sequencing). We show the client output in bold. You'll want to refer to the client source, as well as the bean implementation code, for CustomerBean.java in Listing 6.13 on page 237 as you examine this output. Here's the output (with annotations in italics following each chunk).
get a home interface object
setEntityContext()
ejbCreate(), name=Lydia
ejbPostCreate(), name=Lydia
ejbStore(), name=Lydia
The EJB container calls setEntityContext() before calling ejbCreate() with the client's values. Method ejbCreate() inserts a new record in the database. Method ejbStore() does not update the database.
setEntityContext() Call setPassword() ejbActivate() ejbLoad() dbLoadCustomer: Catherine ejbStore(), name=Catherine dbStoreCustomer: Catherine Call getName() ejbLoad() dbLoadCustomer: Catherine ejbStore(), name=Catherine name = Catherine
The EJB container calls setEntityContext() before invoking method ejbFindByPrimaryKey() with key 101. The container must activate this entity bean and call ejbLoad() to read the database (through dbLoadCustomer()).
After we change the password, ejbStore() must write the new values to the database (through dbStoreCustomer()).
The container invokes ejbLoad() again before invoking business method getName(). Method getName() does not modify the persistent variables, so ejbStore() does not update the database this time.
setEntityContext()
ejbFindAll()
ejbLoad()
dbLoadCustomer: Catherine
ejbStore(), name=Catherine
ejbLoad()
dbLoadCustomer: Catherine
ejbStore(), name=Catherine
Catherine: New Password
We now get all Customer records using findAll(). The container invokes setEntityContext() just once for the finder method.
For primary key 101 (name Catherine), the bean is already activated (no call to ejbActivate() appears). (Note that for each record the container invokes ejbLoad() and ejbStore() twice: once for getName() and again for getPassword().) For these business methods, ejbStore() does not update the database.
ejbActivate()
ejbLoad()
dbLoadCustomer: Maheu
ejbStore(), name=Maheu
ejbLoad()
dbLoadCustomer: Maheu
ejbStore(), name=Maheu
Maheu: Password102
. . .
For the next Customer record (Maheu), the container calls ejbActivate() to activate this bean and ejbLoad() to initialize the persistent variables. Calls to ejbStore() do not update the database.
ejbLoad() dbLoadCustomer: Lydia ejbStore(), name=Lydia ejbLoad() dbLoadCustomer: Lydia ejbStore(), name=Lydia Lydia: Lydiapassword setEntityContext() ejbHomeGetTotalCustomers() 6 customers in database.
Our newly created Customer record (Lydia) is the final record returned by findAll(). Again, ejbActivate() is not necessary since this entity bean is already activated. Following the output for customer Lydia, the next two lines show the server output for accessing the home method getTotalCustomers() (with the client output appearing in the last line).
18.118.121.54