C H A P T E R 3 |
Building the EJB Tier of the DiningGuide Application |
This chapter describes, step by step, how to create the EJB tier of the DiningGuide tutorial application. Along the way, you learn how to use the EJB Builder to create both entity and session beans, and how to use the IDE's test mechanism to test the beans. The topics covered in this chapter are:
By the end of this chapter, you will be able to run the whole EJB tier of the DiningGuide application as a deployed test application.
After you have created the EJB tier, you are free to create your own web services and client pages. Alternatively, you can continue on to Chapter 4, to learn how to create the application's web services using the Sun ONE Studio 4 Web Services features.
In this chapter, you create the module that is the heart of the tutorial application, namely, its EJB tier. As you create each component, you test it using the IDE's test application facility, which automatically creates a test web service and test client.
The EJB tier you create will include:
For a complete discussion of the role of the EJB tier within J2EE architecture, see Building Enterprise JavaBeans Components in the Sun ONE Studio 4 Programming series. That document provides full descriptions of all the bean elements, and explains how transactions, persistence, and security are supported in enterprise beans.
To examine an application that also uses an EJB tier and a web service generated from it, see the PartSupplier example on the Sun ONE Studio 4 examples page, http://forte.sun.com/ffj/documentation/tutorialsandexamples.html
An entity bean provides a consistent interface to a set of shared data that defines a concept. In this tutorial, there are two concepts: restaurant and customer review. The Restaurant and Customerreview entity beans that you create represent the database tables you created in Chapter 1.
Entity beans can have either container-managed persistence (CMP) or bean-managed persistence (BMP). With a BMP entity bean, the developer must provide code for mapping the bean's fields to the database table columns. With a CMP entity bean, the EJB execution environment manages persistence operations. In this tutorial, you use CMP entity beans. Using the IDE's EJB Builder wizard, you connect to the database and indicate which columns to map. The wizard creates the entity beans mapped to the database.
The EJB Builder creates the CMP entity bean's framework, including the required home interface, remote interface, and bean class. The wizard also creates a logical node to organize and facilitate customization of the entity bean.
You manually define the entity bean's create, finder, and business methods. When you define these methods, the IDE automatically propagates the method to the appropriate bean components. For example, a create method is propagated to the bean's home interface and a corresponding ejbCreate method to the bean's class. When you edit the method, the changes are propagated as well.
With finder methods, you must define the appropriate database statements to find the objects you want. The EJB 2.0 architecture defines a database-independent version of SQL, called EJB QL, which you use for your statements. At deployment, the Sun ONE Application Server plugin translates the EJB QL into the SQL appropriate for your database and places the SQL in the deployment descriptor.
Entity beans represent shared data, but session beans access data that spans concepts and is not shared. Session beans can also manage the steps required to accomplish a particular task. Session beans can be stateful or stateless. A stateful session bean performs tasks on behalf of a client while maintaining a continued conversational state with the client. A stateless session bean does not maintain a conversational state and is not dedicated to one client. Once a stateless bean has finished calling a method for a client, the bean is available to service a request from a different client.
In the DiningGuide application, client requests might include obtaining data on all the restaurants in the database or finding all the customer reviews for a given restaurant. Submitting a review for a given restaurant is another client request. These requests are not interrelated, and don't require maintenance of a conversational state. For these reasons, the DiningGuide tutorial uses a stateless session bean to manage the different steps required for each request.
The session bean repeatedly builds collections of restaurant and customer review records to satisfy a client's request. This task could be accomplished by adding getter and setter methods for each field onto the entity beans, but this approach would require calling a method for every field each time the session bean has to retrieve a row of the table. To reduce the number of method calls, this tutorial uses special helper classes, called detail classes, to hold the row data.
A detail class has the same fields as the corresponding entity bean, plus getter and setter methods for each field. When the session bean looks up an entity bean, it uses the corresponding detail class to create an instance of each remote reference returned by the entity bean. The session bean just calls the detail class's constructor to instantiate a row of data for viewing. In this way, the session bean can create a collection of row instances that can be formatted into an HTML page for the client to view.
FIGURE 3-1 shows graphically how the detail classes work.
The numbered items in FIGURE 3-1 signify the following actions:
1. The web container passes a client's request for all restaurant data to the DiningGuideManager session bean.
2. The session bean calls the Restaurant entity bean's findAll method to perform a lookup on the Restaurant entity bean.
3. The findAll method obtains all available remote references to the entity bean.
4. For each remote reference returned, the session bean calls the Restaurant bean's getRestaurantDetail business method to fetch the RestaurantDetail class.
5. The getRestaurantDetail method returns a RestaurantDetail object, which is added to the collection.
6. The session bean returns a collection of all RestaurantDetail objects to the web container, which formats the data appropriately for the client to view.
Creating the EJB tier requires six steps:
2. Creating detail classes that have the same fields as the entity beans
3. Creating business methods on the entity beans to fetch the detail classes
4. Testing the entity beans' methods with the IDE's test application facility
6. Using the test application facility again to test the session bean
Note - Before you can begin work on the tutorial application, you must first have performed all the setup steps described in Chapter 1. |
Create two entity beans, Restaurant and Customerreview, to represent the two database tables you created in Chapter 1.
In version 2.0 of the EJB architecture, entity beans can have local interfaces, remote interfaces, or both. The criterion for deciding which to use rests on whether the client that calls the bean's methods is remote or local to the bean. In this tutorial, you create the entity beans with both remote and local interfaces, for flexibility regarding how the web service will access the beans' methods. Two possibilities are the session bean accesses the beans' methods (using local interfaces), or the web service accesses the methods directly (using remote interfaces).
Tip - For more details about working with the EJB Builder, see the Sun ONE Studio 4 help topics on EJB components. |
Note - The source code for the completed entity beans is provided in Appendix A. |
First, create a directory to mount as a filesystem to contain the application and create a package for the EJB tier. Next, create database schemas to model the two database tables. Finally, create two entity beans within the package.
Note - The following instructions assume that the Sun ONE Studio 4 IDE and the Oracle server in which you created the tables (see Creating the Database Tables) are both running. |
Create a directory to contain the tutorial's files and mount it in the IDE's file system. Then create a Java package under this directory, as follows:
1. Somewhere on your file system, create a directory and name it DiningGuide2.
This tutorial uses DiningGuide2 for the directory name to distinguish it from the directory name (DiningGuide) given to the tutorial released with Version 4.0 of Sun ONE Studio.
2. In the Sun ONE Studio 4 IDE, choose the File Mount Filesystem.
3. Select Local Directory, and click Next.
The Select Directory pane of the New wizard is displayed.
4. Use the Look In file finder to find the DiningGuide2 directory, select it, and click Finish.
The new directory (for example, c:\DiningGuide2) is mounted in the Explorer.
5. Right-click the new filesystem you just mounted and choose New Java Package.
You will use this package to hold the EJB tier of the application. This tier holds the data of your application.
6. Name the new package Data and click Finish.
The new Data package appears under the DiningGuide2 directory.
Now create database schemas for the Restaurant and Customerreview tables in the Data package, as follows:
1. Right-click the DiningGuide2 node in the Explorer and choose New Databases
Database Schema.
The Name Object pane of the New wizard is displayed.
2. Type restSchema in the Name field and click Next.
The Database Connection pane of the wizard is displayed.
3. Select the New Connection option.
4. Enter values in the fields appropriate to your database.
For example, the following values are correct for a locally installed database with a SID of "extut," and the default Oracle login of "scott" for User Name and "tiger" for Password:
The Tables and Views pane is displayed.
6. Select the RESTAURANT table in the list of available tables and click the Add button.
The RESTAURANT table moves to the list of selected tables and views.
The new database schema appears under the Data package in the Explorer. If you expand all its subnodes, it looks like this:
8. Repeat Step 1 through Step 7 to create a second database schema, named custSchema, for the CustomerReview table.
Name the schema custSchema in Step 2 and select the CUSTOMERREVIEW table in Step 6.
Now create the two entity beans, as follows:
1. Right-click the new Data package and choose New J2EE
CMP Entity EJB.
The CMP Entity Bean Name and Properties pane of the New wizard (used by the EJB Builder module) is displayed. If you click the Help button on any pane of the wizard, you can get context-sensitive help on creating CMP entity beans.
2. Name the new CMP bean Restaurant and select the following options:
Source for Entities and Fields: Table from Database Schema Object
Component Interfaces: Both Remote and Local Interfaces
The New wizard should look like this.
This displays the Table from Database Schema Object pane.
4. Expand the DiningGuide2 node and all the nodes under the restSchema node, and select the RESTAURANT table.
The CMP Fields pane is displayed. You see a side-by-side display of the columns of the Restaurant database table and the corresponding Java fields that the columns will be mapped to when the wizard creates the Restaurant entity bean.
6. Select the rating field and click the Edit button.
The Edit Persistent Field dialog box is displayed.
7. Delete the text for the Type field and type in int.
The dialog box looks like this:
8. Click OK to close the dialog box, then click Next on the wizard's window.
The CMP Entity Bean Class Files pane is displayed, listing the parts of the Restaurant bean that will be created. Notice that the EJB Builder wizard has automatically named the new entity bean with the same name as the database table.
9. Accept all the default labels and click Finish.
The new Restaurant entity bean and all its parts are created and displayed in the Explorer window.
Five of the parts are interfaces and one is the bean class. The sixth part is the logical node that groups all the elements of the enterprise bean together and facilitates working with them.
Create the Customerreview entity bean as you did the Restaurant bean, using the following steps:
1. Right-click the new Data package and choose New J2EE
CMP Entity EJB.
2. Name the new CMP bean Customerreview and select the following options:
Source for Entities and Fields: Table from Database Schema Object
Component Interfaces: Both Remote and Local Interfaces
The Table from Database Schema Object pane is displayed.
4. Expand the DiningGuide2 node and all the nodes under the custSchema node, select the CUSTOMERREVIEW table, and click Next.
5. Click Next on the CMP Fields pane, and click Finish on the last pane (CMP Entity Bean Class Files pane).
The Customerreview entity bean is displayed in the Data package in the Explorer. Notice that there is also a primary key class named CustomerreviewKey. This class is automatically created when the entity bean has a composite primary key. (See TABLE 1-1 in Chapter 1 to confirm the composite primary key in this table.)
6. Choose File Save All to save your work.
Create the create methods for both entity beans, adding parameters and code to initialize the fields of the beans' instances.
Create the create method for the Restaurant entity bean as follows:
1. In the Explorer, right-click the Restaurant(EJB) logical node (the bean icon ).
2. Choose Add Create Method from the contextual menu.
The Add New Create Method dialog box is displayed.
3. Using the Add button, create seven new parameters, one for each column of the Restaurant table:
restaurantname (java.lang.String)
cuisine (java.lang.String)
neighborhood (java.lang.String)
address (java.lang.String)
phone (java.lang.String)
description (java.lang.String)
rating (int)
Note - The order in which you create these parameters becomes important when you test the bean with the test application facility. Create them in the order given here. |
Keep the two exceptions created by default, and make sure the method is added to both Home and Local Home interfaces.
The IDE propagates a create method under the RestaurantHome interface, another create method under the LocalRestaurantHome interface, and an ejbCreate method under the Restaurant bean class (RestaurantBean). A related ejbPostCreate method is also added to the bean class.
5. Expand the Restaurant(EJB) logical node and the Create Methods folder, and double-click the create method.
The Source Editor is displayed with the cursor at placed on the ejbCreate method of the bean.
Note - If you right-click the create method node and choose Help, you can get online help information on create methods. |
6. Add the following code (the bold text only) to the body of the ejbCreate method to initialize the fields of the bean instance:
Tip - After you enter code (either by typing or copying and pasting) into the Source Editor, select the block of code and press Control-Shift F to reformat it properly. |
When the Restaurant entity bean's create method is called, it creates a new record in the database, based on the container-managed fields of this bean.
7. Select the Restaurant(EJB) logical node and press F9 to compile the bean.
The Restaurant entity bean should compile without errors.
Create the create method for the Customerreview entity bean as follows:
1. Right-click the Customerreview(EJB) logical node (the bean icon ) and choose Add Create Method.
2. Use the Add button to create three parameters, one for each column of the CustomerReview table:
restaurantname (java.lang.String)
customername (java.lang.String)
review (java.lang.String)
Note - As in Step 3, create these parameters in the order given. |
Keep the two exceptions created by default, and make sure the method is added to both Home and Local Home interfaces.
4. Open the Customerreview(EJB) logical node and the Create Methods folder, and double-click the create method.
The Source Editor opens with the cursor at the ejbCreate method of the bean.
5. Add the following (bold) code to the body of the ejbCreate method to initialize the fields of the bean instance:
When the ejbCreate method is called, it creates a new record in the database, based on the container-managed fields of this bean.
6. Select the Customerreview(EJB) logical node and press F9 to compile the bean.
The Customerreview entity bean should compile without errors.
Now, create finder methods on both entity beans that will locate all or selected instances of each bean in the context.
Create a findAll method on the Restaurant bean to locate all restaurant data. Also create a findByRestaurantName on the Customerreview bean to locate review data for a given restaurant.
Every finder method, except findByPrimaryKey, must be associated with a query element in the deployment descriptor. When you create the finder methods for these two entity beans, specify SQL statements using a database-independent language specified in the EJB 2.0 specification, namely EJB QL. At deployment time, the application server plugin translates the EJB QL into the SQL of the target database.
To create the Restaurant bean's findAll method:
1. Right-click the Restaurant(EJB) logical node and choose Add Finder Method.
The Add New Finder Method dialog box is displayed.
2. Type findAll in the Name field.
3. Select java.util.Collection for the Return type.
4. Accept the two default exceptions.
5. Define the EJB QL statements, as follows:
6. Make sure the method is added to both Home and Local Home interfaces.
The new findAll method is created in the Local and Local Home interfaces of the Restaurant bean.
Note - If you right-click the Finder Methods node and choose Help, you can get online help information on finder methods. |
8. Select the Restaurant(EJB) logical node and press F9 to compile the bean.
The Restaurant entity bean should compile without errors.
To create the Customerreview bean's findByRestaurantName method:
1. Right-click the Customerreview(EJB) logical node and choose Add Finder Method.
The Add New Finder Method dialog box is displayed.
2. Type findByRestaurantName in the Name field.
3. Select java.util.Collection for the Return type.
4. Click the parameter's Add button.
The Enter New Parameter dialog box is displayed.
5. Type restaurantname for the parameter name.
6. Select java.lang.String for the parameter type.
8. Accept the two default exceptions.
9. Define the EJB QL statements, as follows:
(Which numeral you use depends on the position of the parameter in the finder method. In this case there's only one parameter, so the numeral is "1").
10. Make sure the method is added to both Home and Local Home interfaces.
The new findByRestaurantName method is created in the Local and Local Home interfaces of the Customerreview bean.
12. Select the Customerreview(EJB) logical node and press F9 to compile the bean.
The Customerreview entity bean should compile without errors.
Create a business method for each entity bean that returns a value of one of its parameters. The business method enables you to test the beans later. For Restaurant, create a getRating method; for Customerreview, create a getReview method.
To create the getRating business method for the Restaurant bean:
1. Expand the Restaurant(EJB) logical node, and then expand its Business Methods node.
There are no business methods yet for this entity bean.
2. Expand the Restaurant bean's class (RestaurantBean), and then expand its Methods node.
Every field on the bean has accessor methods, including a getRating method.
These methods are used by the container for synchronization with the data source. To use any of these methods in development, you have to create them as business methods.
3. Right-click the Restaurant(EJB) logical node and choose Add Business Method.
The Add New Business Method dialog box is displayed.
4. Type getRating in the Name field.
5. Type int in the Return Type field.
Accept the default exception (RemoteException), and the designation that the method will be created in both Remote and Local Home interfaces.
7. Expand the Restaurant(EJB) logical node, and expand the Business Methods folder.
The getRating method is now accessible as a business method. When the getRating method is used, it returns the value in the rating column of a selected restaurant record.
8. Right-click the Restaurant(EJB) logical node and choose Validate EJB from the contextual menu.
The Restaurant entity bean should compile without errors. Now, create a similar method for the Customerreview bean.
To create the getReview business method for the Customerreview bean:
1. Right-click the Customerreview(EJB) logical node and choose Add Business Method.
The Add New Business Method dialog box is displayed.
2. Type getReview in the Name field.
3. Select java.lang.String in the Return Type field.
Accept the default exception (RemoteException), and the designation that the method will be created in both Remote and Local Home interfaces.
The getReview method is now accessible as a business method. When the getReview method is called, it returns the value in the review column of a selected restaurant record.
5. Right-click the Customerreview(EJB) logical node and choose Validate EJB from the contextual menu.
The Customerreview entity bean should compile without errors.
6. Check that the icons in the Explorer no longer indicate that the beans are uncompiled.
As discussed in The Detail Classes, this tutorial uses detail classes as a mechanism for holding row data for viewing and reducing method calls to the entity beans. These classes must have the same fields as the corresponding entity beans, access methods for each field, and a constructor that sets each field.
Note - The source code for the completed detail classes is provided in Appendix A. |
First, create a RestaurantDetail class and a CustomerreviewDetail class:
1. In the Explorer, right-click the Data package and choose New Beans
Java Bean.
2. Name the new bean RestaurantDetail and click Finish.
The new bean is displayed in the Explorer.
3. Repeat Step 1 and Step 2 to create the CustomerreviewDetail bean.
Now, add the same bean properties to the classes as those in the corresponding entity beans' CMP fields. (If you look in the Bean Patterns nodes of an entity bean's bean class, you will see that the CMP fields are stored as bean properties.) While adding the fields, you can automatically create accessor methods for each field.
To create the detail class properties and methods:
1. Expand the RestaurantDetail node and the class RestaurantDetail node.
2. Right-click the Bean Patterns node and choose Add Property.
The New Property Pattern dialog box is displayed.
3. Type restaurantname in the Name field.
4. Select String for the Type.
5. Select the Generate Field option.
6. Select the Generate Return Statement option.
7. Select the Generate Set Statement option.
9. Repeat Step 2 through Step 8 to create the following additional properties:
cuisine (String)
neighborhood (String)
address (String)
phone (String)
description (String)
rating (int)
10. Expand the RestaurantDetail bean's Methods node.
Accessor methods have been generated for each field.
11. Expand the CustomerreviewDetail node and the class CustomerreviewDetail node.
12. Repeat Step 2 through Step 8 to create the following properties in the Bean Properties node:
restaurantname (String)
customername (String)
review (String)
To create constructors for the detail classes that instantiate the class fields:
1. Expand the RestaurantDetail bean, right-click the class RestaurantDetail node, and choose Add Constructor.
The Edit New Constructor dialog box is displayed.
2. Add the following method parameters and click OK:
java.lang.String restaurantname
java.lang.String cuisine
java.lang.String neighborhood
java.lang.String address
java.lang.String phone
java.lang.String description
int rating
3. Add the following bold code to the body of this RestaurantDetail constructor to initialize the fields:
Tip - Remember, you can reformat code you paste or type into the Source Editor by selecting the code block and pressing Control-Shift F. |
4. Similarly, add a constructor to the CustomerreviewDetail class with the following parameters:
java.lang.String restaurantname
java.lang.String customername
java.lang.String review
5. Add the following bold code to the body of this CustomerreviewDetail constructor to initialize the fields:
6. Right-click the Data package and choose Compile All.
The package should compile without errors.
Now, create get methods on the entity beans to retrieve instances of the detail classes.
Create a method on each entity bean that returns an instance of its corresponding detail class.
1. In the Explorer, right-click the Restaurant (EJB) logical node and choose Add Business Method.
The Add New Business Method dialog box is displayed.
2. Type getRestaurantDetail in the Name field.
3. For the return type, use the Browse button to select the RestaurantDetail class.
Be sure to select the class (), not the bean's node. Data.RestaurantDetail is displayed in the Return Type field.
4. Accept all other default values and click OK to create the method.
5. Double-click the method to access it in the Source Editor and add the following bold code:
public Data.RestaurantDetail getRestaurantDetail() { return (new RestaurantDetail(getRestaurantname(), getCuisine(), getNeighborhood(), getAddress(), getPhone(), getDescription(), getRating())); } |
6. Select the Restaurant (EJB) logical node and press F9 to compile the code.
7. In the Explorer, right-click the Customerreview (EJB) logical node and choose Add Business Method.
8. Type getCustomerreviewDetail in the Name field.
9. For the return type, use the Browse button to select the CustomerreviewDetail class icon.
10. Accept all other default values and click OK to create the method.
11. Open the method in the Source Editor and add the following bold code:
public Data.CustomerreviewDetail getCustomerreviewDetail() { return (new CustomerreviewDetail(getRestaurantname(), getCustomername(), getReview())); } |
12. Right-click the Data package and choose Compile All.
The entire package should compile without errors.
You have finished creating the entity beans of the tutorial application and their detail class helpers. Your next task is to test the beans.
The Sun ONE Studio 4 IDE includes a mechanism for testing enterprise beans that includes the enterprise bean within a test client application that uses JavaServer Pages technology. You can display the test client pages in a web browser. These pages enable you to create instances of the bean and exercise the bean's create, finder, and business methods.
Use this test client to exercise the Restaurant bean's create and getRating methods.
When you create a test client, the IDE generates an EJB module, a J2EE application module, and many supporting elements.
To create a test client for the Restaurant entity bean:
1. Right-click the Restaurant(EJB) logical node and choose Create New EJB Test Application.
The EJB Test Application wizard is displayed.
The wizard's window looks like this:
A progress monitor appears briefly and then goes away when the process is complete. Another window is displayed informing you that the web module that was created is also visible in the Project tab. It should go away automatically, also. If not, click OK to close the window.
4. View the resulting test objects in the Explorer.
The IDE has created an EJB module named Restaurant_EJBModule, a web module named Restaurant_WebModule (which is also mounted separately), and a J2EE application named Restaurant_TestApp. The web module contains a number of JSP pages that support the test client. The J2EE application includes references to the EJB module and to the web module.
The J2EE application created by the IDE contains references to the web module and the EJB module. You can see these objects by expanding the Restaurant_TestApp:
In order for the test client to find the database and log onto it, you must add information about your database to the application server properties of the EJB module.
To add the required information:
1. Expand the EJB module (Restaurant_EJBModule) in the Explorer and select the Restaurant node (a reference to the Restaurant bean) under it, to display its properties.
If the Properties Window is not already displayed, choose View Properties.
2. Select the Sun ONE AS tab of the Properties window.
Note - If there is no Sun ONE AS tab on the Properties window, there is no instance of the Sun ONE Application Server 7 server in the Server Registry. See Configuring the IDE to Use the Application Server to correct this problem. |
3. Confirm that the following three values for the appropriate properties:
If these values are displayed, continue with Step 5.
4. If the values are not displayed, remap the Restaurant bean as follows:
a. Select the value field of the Mapped Fields value and click on the ellipsis button.
The Map to Database wizard is displayed.
b. Click Next to view the Select Tables pane.
c. Select RESTAURANT from the drop list of the Primary Table field.
If RESTAURANT is not in the list, use the Browse button to find the table with the restSchema schema.
d. Click Next to view the Field Mappings pane.
e. If the fields are unmapped, click the Automap button.
Values for mappings appear for each field, as shown:
The values should now display as in Step 3.
5. Select the EJB module (Restaurant_EJBModule) to display its properties.
6. Select the Sun ONE AS tab of the properties window.
7. Click in the value field for the CMP Resource property to display an ellipsis button.
8. Click the ellipsis button to display the CMP Resource property editor.
9. Type jdo/OraclePm in the Jndi Name field.
This is the JNDI name of the JDBC Persistence Manager you defined in Defining a JDBC Persistence Manager.
10. For the Name and Password fields, type the User Name and Password for your database.
You specified this name and password when you defined the connection pool in Defining a JDBC Connection Pool. The editor looks similar to this:
11. Click OK to accept the values and close the property editor.
You have finished configuring the test application to use your database and now you can deploy the test application.
Note - Make sure the Oracle server is running before you deploy the test application, or any other J2EE application that accesses the database. In addition, make sure the Sun ONE Application Server 7 server is running and is the default application server of the IDE. See Making the Sun ONE Application Server the Default Server for information. |
To deploy the Restaurant test application:
Right-click the Restaurant_TestApp J2EE application node and choose Execute from the contextual menu.
A Progress Monitor window shows the progress of the deployment process. The server instance's log file tab on the output window displays progress messages. The application is successfully deployed when you see success messages.
The IDE starts the default web browser and displays the test application's home URL, similar to http://localhost/Restaurant_TestApp/ if your application server is installed locally; localhost will be replaced by your server's host name if it is installed remotely.
Your browser displays the test client like this:
On the test client's web page that is displayed, use the create method of the Restaurant bean's home interface to create an instance of the bean. Then test a business method (in this case, getRating) on that instance.
1. Create an instance of the Restaurant bean by invoking the create method.
The create method is under the heading "Invoke Methods on Data.RestaurantHome." There are seven fields under it. The fields are not named, but you can deduce what they are by their order, which is the same order you created them in (see Step 3 under Creating Create Methods for CMP Entity Beans).
Note - Double-click the Restaurant.create method in the Explorer to display it in the Source Editor; the order of the fields is shown in the method's definition. |
Type any data you like into the fields, for example (your field order may be different):
2. Click the Invoke button next to the create method.
The deployed test application adds the records you created to the test database. The new Restaurant instance is listed by its restaurantname value in the upper left, and new data objects are listed in the upper right, as shown.
The results are shown in the Results area.
3. Test the findAll method of the Restaurant bean by clicking the Invoke button next to it.
The results area should look like this:
Notice that three items were returned. This demonstrates that the new database record you created in Step 2 was added to the two you created in Chapter 1.
4. Test the findByPrimaryKey method by typing in Bay Fox and clicking the Invoke button next to the method.
The results area shows that the Bay Fox record was returned.
Now, test the entity bean's business methods.
5. Select the instance for Joe's House of Fish listed under Data.RestaurantHome in the instances list (upper left).
The getRating method is now listed under the Invoke Methods area.
6. Click the Invoke button next to the getRating method.
The results of this action are listed in the Results area and should look like this:
This demonstrates that you have created a new record in the database and used the getRating method to retrieve the value of one of its fields.
Continue testing by selecting created objects and invoking their methods. For example, if you select one of the Data.RestaurantDetail objects, you can invoke its getter methods to view its data, or its setter methods to write new data to the database.
7. When you are finished testing, you can quit the browser, point it to a different URL, or do nothing, as you wish
To verify that the Restaurant_TestApp application inserted data in the database:
Refer to under Creating the Database Tables.
2. Copy the following SQL into the Oracle console:
If you entered the values in Step 1 under Using the Test Client to Test the Restaurant Bean, the results should look like this:
You are now ready to create the session bean.
Create a test client for the Customerreview entity bean by repeating all the steps in Creating a Test Client for the Restaurant Bean, but using values appropriate to the Customerreview bean.
To summarize creating the test client application:
1. Select the Customerreview(EJB) logical bean and choose Create a new EJB Test Application.
2. Accept all default values and click OK.
Add database information for the plugin, similar to the description in Providing the Sun ONE Application Server 7 Plugin With Database Information, using values appropriate to the Customerreview bean.
To summarize adding database information to the plugin:
1. Expand the EJB module (Customerreview_EJBModule), select the Customerreview node under it, and display its properties.
2. Select the Sun ONE AS tab of the Properties window.
3. Confirm that the following three values for the appropriate properties:
If these values are displayed, continue with Step 5.
4. If the values are not displayed, remap the Customerreview bean as follows:
a. Set the Mapped Schema to Data/custSchema.
b. Set the Mapped Primary Table to CUSTOMERREVIEW.
c. Click the ellipsis button in the value field of the Mapped Fields property.
d. In the wizard, click Next to view the Select Tables pane.
e. Select CUSTOMERREVIEW from the drop list of the Primary Table field.
f. Click Next to view the Field Mappings pane.
g. If the fields are unmapped, click the Automap button.
5. Display the EJB module (Customerreview_EJBModule) properties.
6. Select the Sun ONE AS tab of the properties window.
7. Click the ellipsis button in the value field of the CMP Resource property.
8. In the CMP Resource property editor, type jdo/OraclePm in the Jndi Name field.
9. For the Name and Password fields, type the User Name and Password for your database.
Use the name and password you used when you defined the connection pool in Defining a JDBC Connection Pool.
10. Click OK to accept the values and close the property editor.
Note - Make sure the Oracle server is running before you deploy the test application, or any other J2EE application that accesses the database. In addition, make sure the Sun ONE Application Server 7 server is running and is the default application server of the IDE. See Making the Sun ONE Application Server the Default Server for information. |
To deploy the Customerreview test application:
Right-click the Customerreview_TestApp J2EE application node and choose Execute from the contextual menu.
A Progress Monitor window shows the progress of the deployment process. The server instance's log file tab on the output window displays progress messages. The application is successfully deployed when you see success messages.
The IDE starts the default web browser and displays the test application's home URL, http://localhost/Customerreview_TestApp/ if your application server is installed locally; localhost will be replaced by your server's host name if it is installed remotely if it is installed remotely.
On the test client's web page, use the create method of the Customerreview bean's home interface to create an instance of the bean. Then test a business method (in this case, getCustomerreview) on that instance.
To test the Customerreview bean:
1. Create an instance of the Customerreview bean by invoking the create method.
The create method is under the heading "Invoke Methods on Data.CustomerreviewHome." There are three fields under it.
2. Type values in the three fields.
Type any data you like into the fields, for example (your field order may be different):
3. Click the Invoke button next to the create method.
The deployed test application adds the records you created to the test database. The new Restaurant instance is listed by its restaurantname value in the upper left, and new data objects are listed in the upper right, as shown.
4. In the field for the findByRestaurantName method, type French Lemon and click the Invoke button.
The results look like this, showing that the French Lemon record was returned:
5. In the Navigation cell (upper left), select the Customerreview instance.
6. Find the instance's getReview method and click its Invoke button.
The results display the customer review of the instance you created in Step 2 and Step 3, for example:
Continue testing by selecting created objects and invoking their methods.
7. When you are finished testing, you can quit the browser, point it to a different URL, or do nothing, as you wish.
To verify that the Customerreview_TestApp application inserted data in the database:
Refer to under Creating the Database Tables.
2. Copy the following SQL into the Oracle console:
You will see a new record of the values you entered in Step 1 under Testing the Customerreview Entity Bean.
Create a stateless session bean to manage the conversation between the client (the web service you will create in Chapter 4) and the entity beans.
Note - The source code for the completed session bean is provided in Appendix A. |
In version 2.0 of the EJB architecture, session beans can have local interfaces, remote interfaces, or both. In this tutorial, the session beans' methods will be called by the test application (which is local to the session bean), the web services (also local), and the client (remote). Therefore, create a session bean with both local and remote interfaces.
1. In the Sun ONE Studio 4 Explorer, right-click the Data package and choose New J2EE
Session EJB.
The New wizard is displayed, displaying the Session Bean Name and Properties pane.
2. Type DiningGuideManager in the Name field.
3. Select Stateless for the State option.
4. Select Container Managed for the Transaction Type option.
5. Select Both Remote and Local Interfaces for the Component Interfaces option.
The Session Bean Class Files pane of the wizard is displayed, listing all the components that will be created for this session bean.
Notice that the names of the all the components are based on DiningGuideManager.
The new DiningGuideManager session bean is displayed in the Explorer.
Now create the session bean's methods.
The create method was created when you created the DiningGuideManager session bean. You will now modify it.
Create methods of stateless session beans have no arguments, because session beans do not maintain an ongoing state that needs to be initialized. The create method of the DiningGuideManager session bean must first create an initial context, which it then uses to get the required remote references.
1. Double-click the DiningGuideManager's create method to display it in the Source Editor.
Use the logical node (DiningGuideManager(EJB)) to locate the method.
2. Begin coding the method with a JNDI lookup for a remote reference to the RestaurantHome interface.
Note - Remember, you can reformat the code you enter in the Source Editor by selecting it and pressing Control-Shift F. Also remember to remove line breaks when indicated by the code comments. |
3. Under the preceding code, add a similar JNDI lookup for the CustomerreviewHome interface.
4. Now add an import statement for the javax.naming package.
Add the import statement at the top of the file. You must import javax.naming because it contains the lookup method you just used.
import javax.naming.*; |
5. Declare the myRestaurantHome and myCustomerreviewHome fields.
Add these declarations to the definition of the DiningGuideManagerEJB session bean after the import statements.
6. Select the (DiningGuideManager(EJB) logical node and press F9 to compile the bean.
Next, create the DiningGuideManager's business methods.
The DiningGuideManager bean requires a method that retrieves all restaurant data when it receives a request from the client to see the list of restaurants. It also requires a method to retrieve review data for a specific restaurant when the client requests a list of customer reviews. Create the getAllRestaurants and getCustomerreviewsByRestaurant methods to satisfy these requirements.
To create the getAllRestaurants business method:
1. Right-click the DiningGuideManager logical node and choose Add Business Method.
The Add New Business Method dialog box is displayed.
2. Type getAllRestaurants in the Name field.
3. Type java.util.Vector in the Return Type field.
4. Accept all other default values and click OK.
The method shell is created in the DiningGuideManager session bean's business methods.
5. Open the method in the Source Editor and add the following (bold only) code:
This code gets an instance of RestaurantDetail for each remote reference of the Restaurant bean in the context, adds it to a vector called restaurantList, and returns this vector.
6. Select the DiningGuideManager(EJB) logical node and press F9 to compile the bean.
Now, create a similar method to get a list of customer reviews.
To create the getCustomerreviewsByRestaurant method:
1. Right-click the DiningGuideManager logical node and choose Add Business Method.
The Add New Business Method dialog box is displayed.
2. Type getCustomerreviewsByRestaurant in the Name field.
3. Type java.util.Vector in the Return Type field.
4. Click the Add button to add a parameter.
The Add New Parameter dialog box is displayed.
5. Type restaurantname in the Field Name field.
6. Select java.lang.String in the Type field.
7. Click OK to close the dialog box and create the method parameter.
8. Accept all other default values and click OK again create the business method.
The method is created in the DiningGuideManager session bean.
9. Find the method in the Source Editor and add the following bold code:
Similar to the getAllRestaurants code, this method retrieves an instance of CustomerreviewDetail for each remote reference of the Customerreview bean in the context, adds it to a vector called reviewList and returns this vector.
10. Select the DiningGuideManager(EJB) logical node and press F9 to compile the bean.
Now create a business method that calls the Customerreview entity bean's create method to create a new record in the database.
To create the createCustomerreview method:
1. Right-click the DiningGuideManager logical node and choose Add Business Method.
The Add New Business Method dialog box is displayed.
2. Type createCustomerreview in the Name field.
3. Type void in the Return Type field.
4. Click the Add button to add a parameter.
The Add New Parameter dialog box is displayed.
5. Type restaurantname in the Field Name field.
6. Type java.lang.String in the Type field.
7. Click OK to close the dialog box and create the method parameter.
8. Repeat Step 4 through Step 7 twice to create the following two parameters:
java.lang.String customername
java.lang.String review
9. Click OK again create the business method.
The method is created in the DiningGuideManager session bean.
10. Find the method in the Source Editor and add the following bold code:
Note - Make sure you eliminate the three line breaks indicated by the comments. |
11. Select the (DiningGuideManager(EJB) logical node again and press F9 to compile the bean.
The web service you will create in Chapter 4 is a JAX-RPC implementation of the SOAP RPC web service. SOAP (Simple Object Access Protocol) is an abstract messaging technique that allows web services to communicate with one another using HTTP and XML. The SOAP runtime must know of all the Java types employed by any methods that are called by the web service in order to map them properly into XML. Because the tutorial's web service will call session bean methods, it needs to know every type used by those methods.
One type the SOAP runtime can not have knowledge of is the type of objects that make up collections. The methods that you just created (getAllRestaurants and getCustomerreviewsByRestaurant) all return collections of the detail classes. You must provide knowledge of these classes to the SOAP runtime by creating, for each detail class, a method that returns the class. The methods you will create are the getRestaurantDetail and getCustomerreviewDetail methods.
You created methods with the same names on the entity beans (see Creating Business Methods on the Entity Beans to Fetch the Detail Classes), but the methods you create now are empty, their purpose being simply to supply the required return type to the SOAP runtime.
For more information on Sun ONE Studio 4 web services and the SOAP runtime, see Building Web Services in the Sun ONE Studio 4 Programming series.
To create the getRestaurantDetail method:
1. Right-click the DiningGuideManager logical node and choose Add Business Method.
The Add New Business Method dialog box is displayed.
2. Type getRestaurantDetail in the Name field.
3. For the return type, use the Browse button to select the RestaurantDetail class.
Be sure to select the class (), not the bean's node. Data.RestaurantDetail is displayed in the Return Type field.
4. Accept all default values and click OK to create the business method and close the dialog box.
The method is created in the DiningGuideManager session bean.
5. Find the method in the Source Editor and add the following bold code:
public Data.RestaurantDetail getRestaurantDetail() { return null; } |
To create the getCustomerreviewDetail method:
1. Right-click the DiningGuideManager logical node and choose Add Business Method.
The Add New Business Method dialog box is displayed.
2. Type getCustomerreviewDetail in the Name field.
3. For the return type, use the Browse button to select the CustomerreviewDetail class.
Data.CustomerreviewDetail is displayed in the Return Type field.
4. Click OK to create the business method and close the dialog box.
The method is created in the DiningGuideManager session bean.
5. Find the method in the Source Editor and add the following bold code:
public Data.CustomerreviewDetail getCustomerreviewDetail() { return null; } |
6. Right-click DiningGuideManager(EJB) and choose Validate EJB.
The DiningGuideManager session bean should validate without errors.
When you deploy a session bean, the bean's properties must contain references to any entity beans methods called by the session bean. Add them to the session bean now; you can not add them after the bean has been assembled into an EJB module.
1. In the Explorer, select the DiningGuideManager(EJB) logical node.
2. Display the bean's property sheet.
If the Properties window is not already visible, choose View Properties.
3. Select the References tab of the property window.
4. Click the EJB References field and then click the ellipsis (...) button.
The EJB References property editor is displayed.
The Add EJB Reference property editor is displayed.
6. Type ejb/Restaurant in the Reference Name field.
7. For the Referenced EJB Name field, click the Browse button.
The Select an EJB browser is displayed.
8. Select the Restaurant (EJB) bean under the DiningGuide2/Data node and click OK.
Notice that the Home and Remote interface fields are automatically filled.
9. Set the Type field to Entity.
The Add EJB Reference property editor looks like this:
10. Select the Sun ONE App Server tab.
11. Type ejb/Restaurant in the JNDI Name field and click OK.
This is the default JNDI name that was assigned to the Restaurant bean when you created it.
12. Repeat Step 5 through Step 11 to add a reference to the Customerreview entity bean.
The EJB References dialog box looks like this:
13. Click OK to close the Property Editor window.
You have now completed the EJB Tier of the tutorial application and are ready to test it. As when you tested the entity beans, the IDE's test application facility creates a web tier and JSP pages that can be read by a client in a browser.
Use the IDE's test application facility to test the DiningGuideManager session bean. This will test the whole EJB tier, because the session bean's methods provide access to methods on all of the tier's components.
Create a test application from the DiningGuideManager bean. Then add the two entity beans to the EJB module.
To create a test client for the session bean:
1. Right-click the DiningGuideManager logical node and choose Create New EJB Test Application.
The EJB Test Application wizard is displayed.
2. Accept all default values and click OK.
A progress monitor appears briefly and then goes away when the process is complete. Another window is displayed informing you that the web module that was created is also visible in the Project tab. It should go away automatically, also. If not, click OK to close the window.
3. View the resulting test objects in the Explorer.
The IDE has created the following objects:
The EJB module and web module appear as subnodes under the Data package and also as modules contained in the J2EE application. The web module has also been mounted separately.
The EJB module contains only the DiningGuideManager bean, so you must add the two entity beans to it.
4. Right-click the DiningGuideManager_EJBModule and choose Add EJB.
The Add EJB to EJB Module browser is displayed.
5. Expand the DiningGuide2 filesystem and the Data package.
6. Using Control-Click, select both the Restaurant and Customerreview logical beans.
The DiningGuideManager_EJBModule should look like this:
You must add database information to the Sun ONE Application Server 7 properties of the EJB module. You performed this task with the entity bean test client in Providing the Sun ONE Application Server 7 Plugin With Database Information.
To add the required information:
1. Expand the EJB module (DiningGuideManager_EJBModule) in the Explorer and select the Restaurant node (a reference to the Restaurant bean) under it, to display its properties.
If the Properties Window is not already displayed, choose View Properties.
2. Select the Sun ONE AS tab of the Properties window.
Note - If there is no Sun ONE AS tab on the Properties window, there is no instance of the Sun ONE Application Server 7 server in the Server Registry. See Configuring the IDE to Use the Application Server to correct this problem. |
3. Confirm that the following three values for the appropriate properties:
If these values are displayed, continue with Step 5.
4. If the values are not displayed, remap the Restaurant bean as follows:
a. Set the Mapped Schema property to Data/restSchema.
b. Set the Mapped Primary Table property to Restaurant.
c. Click in the value field of the Mapped Fields, then click on the ellipsis button.
The Map to Database wizard is displayed.
d. Click Next to view the Select Tables pane.
e. Select RESTAURANT from the drop list of the Primary Table field.
If RESTAURANT is not in the list, use the Browse button to find the table with the restSchema schema.
f. Click Next to view the Field Mappings pane.
g. If the fields are unmapped, click the Automap button.
Values for mappings appear for each field.
The values should now display as in Step 3.
5. Repeat Step 1 through Step 4 (if required) for the Customerreview reference.
6. Select the EJB module (DiningGuideManager_EJBModule) to display its properties.
7. Select the Sun ONE AS tab of the properties window.
8. Click in the value field for the CMP Resource property, then click the ellipsis button.
The CMP Resource property editor is displayed.
9. Type jdo/OraclePm in the Jndi Name field.
This is the JNDI name of the JDBC Persistence Manager you defined in Defining a JDBC Persistence Manager.
10. For the Name and Password fields, type the User Name and Password for your database.
You specified this name and password when you defined the connection pool in Defining a JDBC Connection Pool. The editor looks similar to this:
11. Click OK to accept the values and close the property editor.
You have finished configuring the test application to use your database and now you can deploy the test application.
12. Save your work with File Save All.
You must first undeploy the two test applications of the entity beans (if they are still deployed) before you deploy the session bean's test application. This is because they use the same JNDI lookups to the Restaurant and Customerreview beans that are used by the DiningGuideManager_TestApp application. If you fail to undeploy these applications, the DiningGuideManager test application will deploy, but will not load.
To undeploy any previously deployed applications.
1. Click the Explorer's Runtime tab to display the Runtime pane.
2. Expand the server1(hostname:host-number) instance node under the Sun ONE Application Server 7 node under Installed Servers.
3. Select the Deployed Applications node.
The two entity bean test applications are displayed.
5. Right-click one of the applications and choose Undeploy.
The application is undeployed.
6. Repeat Step 5 to undeploy the other application.
7. Restart the server instance.
a. Right-click the server1(hostname:host-number) node and choose Status.
The Server Status window is displayed.
b. Click the Stop Server Instance button.
c. When the instance is stopped, click the Start Server Instance button.
The server's command window appears.
d. When the messages in the command window indicate that the server instance is restarted, click OK to close the Server Status dialog box.
Note - Make sure the Oracle server is running before you deploy the test application, or any other J2EE application that accesses the database. In addition, make sure the Sun ONE Application Server 7 server is running and is the default application server of the IDE. See Making the Sun ONE Application Server the Default Server for information. |
To deploy the DiningGuideManager test application:
1. Click the Explorer's Filesystems tab to display the Filesystems pane.
2. Right-click the DiningGuideManager_TestApp J2EE application node and choose Execute from the contextual menu.
A Progress Monitor window shows the progress of the deployment process. The server instance's log file tab on the output window displays progress messages. The application is successfully deployed when you see success messages.
The IDE starts the default web browser and displays the test application's home URL, similar to http://localhost/DiningGuideManager_TestApp/ if your application server is installed locally; it will be different if it is installed remotely.
On the test client's web page, create an instance of the DiningGuideManager session bean by exercising the create method; then test the business methods (getRating) on that instance.
To test the DiningGuideManager bean:
1. Create an instance of the DiningGuideManager session bean by invoking the DiningGuideManagerHome's create method.
The Data.DiningGuideManager[x] instance appears in the instance list. Now you can test the bean's getter methods.
2. Select the new Data.DiningGuideManager[x] instance.
The getAllRestaurants and getCustomerreviewsByRestaurant methods are made available.
3. Type any data you like in the createCustomerreview fields.
4. Click the Invoke button next to the createCustomerreview method.
The deployed test application adds the record you created to the database. The new parameter values are listed in the Stored Objects section (upper right), and the results are shown in the Results area:
5. Click the Invoke button on the getAllRestaurants method.
If you created Joe's House of Fish in the database (in Using the Test Client to Test the Restaurant Bean), a vector of size 3 appears in the list of created objects (upper right), and the results of the method invocation should look as shown (actual numbers may be different). If you didn't create this record, your results might be different.
6. Click the Invoke button on the getCustomerreviewDetail method.
The result is shown in the Results section.
7. Type Joe's House of Fish in the field for the getCustomerreviewsByRestaurant method and click the Invoke button.
No CustomerreviewDetail records should be returned, because there are no customer review comments in the database. Now try the French Lemon record.
8. Type French Lemon in the same field and invoke the method.
Two CustomerreviewDetail records should be returned:
9. Click the Invoke button on the getCustomerreviewDetail method.
The result is shown in the Results section.
10. When you are finished testing, stop the test client by pointing your web browser at another URL or by exiting the browser (or do nothing).
To verify that the DiningGuideManager_TestApp application inserted data in the database, repeat the procedures described in Checking the Additions to the Database and Checking the Additions to the Database.
You are now ready to create the web service.
Congratulations, you have successfully completed the EJB tier of the DiningGuide application. You are ready to go on to Chapter 4, to use the Sun ONE Studio 4 IDE's Web Services module to create web services for the application, and then on to Chapter 5 to install the provided Swing classes for your client.
You may, however, wish to create your own web services and client, in which case, the Sun ONE Studio 4 test application can offer some guidelines.
Web services that access a session bean like the DiningGuideManager bean must include a servlet and JSP pages with lookup methods for obtaining the Home interfaces and Home objects of the entity beans in the EJB tier. The web module created by the test application facility offers examples of the required code.
Lookup method examples are found in the EjbInvoker class under the web module. Specifically, look for this class under the WEB-INF/Classes/com/sun/forte4j/j2ee/ejbtest/webtest directory.
For example, the following methods offer good example lookup code:
Copyright © 2002, Sun Microsystems, Inc. All rights reserved.