Discover how to build, deploy, and use CMP (container managed persistence) beans to split the work between the component developer and the container within your Java application.
This material is from the book JBuilder Developer's Guide.
© Copyright Sams Publishing. All rights reserved.
It is now time to look at the process of building an entity bean. We will develop a simple CMP bean, but spend most of our time investigating and perfecting the process.
The process has some similarities to creating session beans. The following is the process we are going to use to investigate and build an entity bean:
Implement the home interface.
Define the appropriate finder methods.
Implement the component interface.
Define the bean implementation class.
Build the deployment descriptor.
Deploy the bean.
Test the bean.
Defining the Home Interface
The home interface for an entity bean is similar to the home interface of a session bean. To review, its purpose is to create an instance, find existing instances, or remove an instance; the same rules apply to an entity bean (see Listing 1).
Listing 1 Home Interface for Our Employee Entity Bean
import javax.ejb.*;
import java.util.*;
public interface EmployeeHome extends javax.ejb.EJBLocalHome {
public Employee create(Short empNo) throws CreateException;
public Employee findByPrimaryKey(Short empNo) throws FinderException;
}
The create() method is used to create an instance of a class based on this primary key. For our employee table, the empNo is the primary key, thus we will also use empNo as the primary key of our entity bean. The second method type is called a finder method. With entity beans, to create an instance we use the create() method, but finding an existing instance is just as important if not more important. With that requirement, we need finder methods to provide the capability to locate a specific instance or collection of instances of data.
The findByPrimaryKey() is a method that has an argument representing the primary key; in our case, it is empNo. This searches for an employee with the given primary key either returning a remote interface to the instance or through an exception.
Note
The findByPrimaryKey() method is required by all entity beans;
any other finders are optional.
Finder methods do not just return a single instance, but they can also return a collection of instances. These types of finder methods are typically used when the primary key or an alternative unique key is not used. For example, we might want to be able to find employees who have a certain salary range, as shown in Listing 2. This finder method should return a collection of employees rather than a single instance.
Listing 2 Home Interface for Our Employee Entity Bean with the Addition of New Finder Methods
import javax.ejb.*;
import java.util.*;
import java.math.*;
public interface EmployeeHome extends javax.ejb.EJBLocalHome {
public Employee create(Short empNo) throws CreateException;
public Collection findSalaryRange(BigDecimal low, BigDecimal high) throws FinderException;
public Employee findByPrimaryKey(Short empNo) throws FinderException;
}
Notice that the findSalaryRange() does not return a single instance like the findByPrimaryKey() but a java.lang.Collection. This collection contains instances of the primary key, not the entire instance; the container then translates for you this instance into the remote interface. This method might return a huge collection of records, so it is important to make sure that you design the beans appropriately.
Defining the Component Interface
Our Employee interface defines all the methods required for us to access and mutate the data within the bean. For example, setFirstName() and getFirstName() methods are required to get access to the instance variables (see Listing 3).
Listing 3 Component Interface for the Employee Bean
import javax.ejb.*;
import java.util.*;
import java.sql.*;
import java.math.*;
public interface Employee extends javax.ejb.EJBLocalObject {
public Short getEmpNo();
public void setFirstName(String firstName);
public String getFirstName();
public void setLastName(String lastName);
public String getLastName();
public void setPhoneExt(String phoneExt);
public String getPhoneExt();
public void setHireDate(Timestamp hireDate);
public Timestamp getHireDate();
public void setDeptNo(String deptNo);
public String getDeptNo();
public void setJobCode(String jobCode);
public String getJobCode();
public void setJobGrade(Short jobGrade);
public Short getJobGrade();
public void setJobCountry(String jobCountry);
public String getJobCountry();
public void setSalary(BigDecimal salary);
public BigDecimal getSalary();
public void setFullName(String fullName);
public String getFullName();
}
Implementing the Bean
One misconception about CMP beans is that you do not have to have a bean implementation class. This class supplies the necessary implementations required for the container to manage the persistence, as shown in Listing 4.
Listing 4 EmployeeBean Implementation Class
import javax.ejb.*;
abstract public class EmployeeBean implements EntityBean {
EntityContext entityContext;
public java.lang.Short ejbCreate(java.lang.Short empNo) throws CreateException {
setEmpNo(empNo);
return null;
}
public void ejbPostCreate(java.lang.Short empNo) throws CreateException {
/**@todo Complete this method*/
}
public void ejbRemove() throws RemoveException {
/**@todo Complete this method*/
}
public abstract void setEmpNo(java.lang.Short empNo);
public abstract void setFirstName(java.lang.String firstName);
public abstract void setLastName(java.lang.String lastName);
public abstract void setPhoneExt(java.lang.String phoneExt);
public abstract void setHireDate(java.sql.Timestamp hireDate);
public abstract void setDeptNo(java.lang.String deptNo);
public abstract void setJobCode(java.lang.String jobCode);
public abstract void setJobGrade(java.lang.Short jobGrade);
public abstract void setJobCountry(java.lang.String jobCountry);
public abstract void setSalary(java.math.BigDecimal salary);
public abstract void setFullName(java.lang.String fullName);
public abstract java.lang.Short getEmpNo();
public abstract java.lang.String getFirstName();
public abstract java.lang.String getLastName();
public abstract java.lang.String getPhoneExt();
public abstract java.sql.Timestamp getHireDate();
public abstract java.lang.String getDeptNo();
public abstract java.lang.String getJobCode();
public abstract java.lang.Short getJobGrade();
public abstract java.lang.String getJobCountry();
public abstract java.math.BigDecimal getSalary();
public abstract java.lang.String getFullName();
public void ejbLoad() {
/**@todo Complete this method*/
}
public void ejbStore() {
/**@todo Complete this method*/
}
public void ejbActivate() {
/**@todo Complete this method*/
}
public void ejbPassivate() {
/**@todo Complete this method*/
}
public void unsetEntityContext() {
this.entityContext = null;
}
public void setEntityContext(EntityContext entityContext) {
this.entityContext = entityContext;
}
}
The client first calls the create() method of the entity bean's home interface. Remember that this is the client of the bean, not necessarily an end-user client. This then translates through the container to the implementation bean. These methods are called by the container for the persistence to take place properly. Let's take a look in detail at how the bean actually works. The best method to view the operation is to use a sequence diagram.
First, let's look at the creation of a new instance of an entity bean,
as shown in Figure 1. The create()
method tags arguments, which is typically a signature containing the primary
key of an instance. After that, the container takes complete control going forward.

Figure 1
Sequence diagram for a client creating an entity bean.
Second, we might need to remove a bean. The remove() method is called
by the client, allowing for the instance to be removed from the data source
(see Figure 2). Again, the only call the
client needs to make is remove(); the container then manages the rest
of the interaction to remove the instance.

Figure 2
Sequence diagram for a client removing an entity bean.
Finally, let's look at a finder method, shown in Figure
3. When the client makes a call to one of the finder methods on the
home interface, the home interface uses the data source to return the matching
elements either singularly using the remote interface or by a list using a
java.lang.Collection.

Figure 3
Sequence diagram for a client using one of the finder methods.
Deployment Descriptor
The role of the deployment descriptor is to ultimately provide information
about each EJB that is to be bundled and deployed within a particular JAR
file. Its intent is to inform the consumer, in this case the container,
what the JAR file contains and how it is to be implemented. If you are developing
your bean, it is typically your responsibility to create the deployment
descriptor. The deployment descriptor keeps the following information:
-
Defines the types, or names, of the classes for the home/local home
and remote/local interfaces and the bean class.
-
JNDI names, which define the name of the interface advertised to the
naming service.
-
Fields to enable container managed persistence.
-
Transactional policies for the bean's transactional behavior.
-
Security attributes for the enterprise beans.
-
Deployment-specific information; these include special information
for the deployed container brand.
To alleviate the confusion between vendor-specific deployment descriptors
and general deployment descriptors, they are divided into two different
descriptors. The first of which is the deployment descriptor, which contains
the configuration information for our Employee CMP bean (see Listing
5).
Listing 5 Deployment Descriptor Containing Our Employee CMP
Bean (ejb-JAR.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-JAR PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-JAR_2_0.dtd">
<ejb-JAR>
<enterprise-beans>
<entity>
<display-name>Employee</display-name>
<ejb-name>Employee</ejb-name>
<local-home>com.sams.samples.entity.EmployeeHome</local-home>
<local>com.sams.samples.entity.Employee</local>
<ejb-class>com.sams.samples.entity.EmployeeBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.Short</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>Employee</abstract-schema-name>
<cmp-field>
<field-name>empNo</field-name>
</cmp-field>
<cmp-field>
<field-name>firstName</field-name>
</cmp-field>
<cmp-field>
<field-name>lastName</field-name>
</cmp-field>
<cmp-field>
<field-name>phoneExt</field-name>
</cmp-field>
<cmp-field>
<field-name>hireDate</field-name>
</cmp-field>
<cmp-field>
<field-name>deptNo</field-name>
</cmp-field>
<cmp-field>
<field-name>jobCode</field-name>
</cmp-field>
<cmp-field>
<field-name>jobGrade</field-name>
</cmp-field>
<cmp-field>
<field-name>jobCountry</field-name>
</cmp-field>
<cmp-field>
<field-name>salary</field-name>
</cmp-field>
<cmp-field>
<field-name>fullName</field-name>
</cmp-field>
<primkey-field>empNo</primkey-field>
<query>
<query-method>
<method-name>findBySalaryRange</method-name>
<method-params>
<method-param>java.math.BigDecimal</method-param>
<method-param>java.math.BigDecimal</method-param>
</method-params>
</query-method>
<ejb-ql>select OBJECT(e) from employee e where e.salary between (low,high)</ejb-ql>
</query>
</entity>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>Employee</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-JAR>
As you look at this descriptor, you will notice that all the information
regarding our bean is contained within the deployment descriptor. This descriptor
will be deployed in the JAR with the bean. Now let's look at the deployment
descriptor specific to an enterprise application server containerspecifically,
in this case, Borland's Enterprise Server, shown in Listing 6.
Listing 6 Application-Specific Deployment Descriptor for Borland's
Enterprise Server (ejb-borland.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-JAR PUBLIC "-//Borland Software Corporation//DTD Enterprise JavaBeans 2.0//EN"
"http://www.borland.com/devsupport/appserver/dtds/ejb-JAR_2_0-borland.dtd">
<ejb-JAR>
<enterprise-beans>
<entity>
<ejb-name>Employee</ejb-name>
<bean-local-home-name>Employee</bean-local-home-name>
<cmp2-info>
<cmp-field>
<field-name>empNo</field-name>
<column-name>EMP_NO</column-name>
</cmp-field>
<cmp-field>
<field-name>firstName</field-name>
<column-name>FIRST_NAME</column-name>
</cmp-field>
<cmp-field>
<field-name>lastName</field-name>
<column-name>LAST_NAME</column-name>
</cmp-field>
<cmp-field>
<field-name>phoneExt</field-name>
<column-name>PHONE_EXT</column-name>
</cmp-field>
<cmp-field>
<field-name>hireDate</field-name>
<column-name>HIRE_DATE</column-name>
</cmp-field>
<cmp-field>
<field-name>deptNo</field-name>
<column-name>DEPT_NO</column-name>
</cmp-field>
<cmp-field>
<field-name>jobCode</field-name>
<column-name>JOB_CODE</column-name>
</cmp-field>
<cmp-field>
<field-name>jobGrade</field-name>
<column-name>JOB_GRADE</column-name>
</cmp-field>
<cmp-field>
<field-name>jobCountry</field-name>
<column-name>JOB_COUNTRY</column-name>
</cmp-field>
<cmp-field>
<field-name>salary</field-name>
<column-name>SALARY</column-name>
</cmp-field>
<cmp-field>
<field-name>fullName</field-name>
<column-name>FULL_NAME</column-name>
</cmp-field>
<table-name>EMPLOYEE</table-name>
</cmp2-info>
<property>
<prop-name>ejb-designer-id</prop-name>
<prop-type>String</prop-type>
<prop-value>Employee</prop-value>
</property>
</entity>
</enterprise-beans>
<table-properties>
<table-name>EMPLOYEE</table-name>
<column-properties>
<column-name>EMP_NO</column-name>
</column-properties>
<column-properties>
<column-name>FIRST_NAME</column-name>
</column-properties>
<column-properties>
<column-name>LAST_NAME</column-name>
</column-properties>
<column-properties>
<column-name>PHONE_EXT</column-name>
</column-properties>
<column-properties>
<column-name>HIRE_DATE</column-name>
</column-properties>
<column-properties>
<column-name>DEPT_NO</column-name>
</column-properties>
<column-properties>
<column-name>JOB_CODE</column-name>
</column-properties>
<column-properties>
<column-name>JOB_GRADE</column-name>
</column-properties>
<column-properties>
<column-name>JOB_COUNTRY</column-name>
</column-properties>
<column-properties>
<column-name>SALARY</column-name>
</column-properties>
<column-properties>
<column-name>FULL_NAME</column-name>
</column-properties>
<property>
<prop-name>datasource</prop-name>
<prop-type>String</prop-type>
<prop-value>serial://datasources/DataSource</prop-value>
</property>
</table-properties>
<assembly-descriptor />
</ejb-JAR>
Deploying Your Entity Bean
Deploying the bean is exactly the same as deploying the bean with a session
bean. The entity bean we just created must be deployed on an application
server before any client can access the bean. The process varies slightly
depending on the version or brand of your application server. JBuilder insulates
you from most of the differences, but nonetheless you have to know a little
bit about your deployment environment. The process for deploying our bean
is accomplished in two steps:
-
Create an EAR node.
-
Deploy it to the application server.
The topmost archive used for deployment is an Enterprise Archive File (EAR).
The EAR file contains all the JAR and WAR files required for deployment
and execution of our enterprise application. It also contains an application.xml
file describing the manifest to the entire archive. In other words, it allows
you to completely package your application into one deliverable, self-contained
entity.
Let's now create an EAR file for our application, containing at this
point only our session bean:
-
Choose File, New from the menu and select the Enterprise tab.
-
Select the EAR node to add to the project.
-
Specify the name of the EAR file and node name. In this case, keep
the name similar to the sample project SampleBeans.
-
Right-click on the new node SampleBean.EARgrp and select Make.
This creates a SampleBean.EAR, and contained within this is an application.xml
descriptor.
-
Right-click on the SampleBean.EARgrp and choose Deploy Your
Bean. Note: Make sure that your application server is running; if it
is not, start your application server and deploy the bean again.
Using Your Entity Bean
It is easiest to test any bean using the remote interface. If you want
to test your local interface, you must communicate to that local interface
with another object that encapsulates that call with a remote interface.
For example, we will test our local interface using a session bean. But
first let's test our entity bean's remote interface. The test
client in this case only tests the finder method, as shown in Listing 7.
Listing 7 Test Client for Verifying the Operation of Our Employee
Entity Bean (EmployeeTestClient.java)
package testclient;
import javax.naming.*;
import javax.rmi.*;
import com.sams.samples.entity.*;
/**
* <p>Title: Empoyee Entity Test Client</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: SAMS Publishing</p>
* @author SAMS Publishing
* @version 1.0
*/
public class EmployeeTestClient {
private EmployeeRemoteHome employeeRemoteHome = null;
//Construct the EJB test client
public EmployeeTestClient() {
try {
//get naming context
Context ctx = new InitialContext();
//look up jndi name
Object ref = ctx.lookup("EmployeeRemote");
//cast to Home interface
employeeRemoteHome = (EmployeeRemoteHome) PortableRemoteObject.narrow(ref,EmployeeRemoteHome.class);
Short empNo = new Short("5");
EmployeeRemote employee = employeeRemoteHome.findByPrimaryKey(empNo);
System.out.println(employee.getFirstName());
System.out.println(employee.getLastName());
}
catch(Exception e) {
e.printStackTrace();
}
}
//-----------------------------------------------------------------------
// Utility Methods
//-----------------------------------------------------------------------
public EmployeeRemoteHome getHome() {
return employeeRemoteHome;
}
//Main method
public static void main(String[] args) {
EmployeeTestClient client = new EmployeeTestClient();
// Use the getHome() method of the client object to call Home interface
// methods that will return a Remote interface reference. Then
// use that Remote interface reference to access the EJB.
}
}
The other option for our entity bean, or for that matter even a session
bean, is a local interface. This local interface is available only to another
bean running inside the same JVM. Listing 8 is the session bean developed
to test the bean, and Listing 9 is the client used to exercise the session
bean.
Note
The purpose of the local interface is simpleperformance. This
performance gain is accomplished primarily in passing data. With a remote
interface, the data is passed by value. In other words, the data is
copied and serialized to another object on the client. The local interface
passes by reference, giving a huge performance increase.
Listing 8 Session Façade to Access the Employee Entity
Bean (EmployeeFacadeBean.java)
package com.sams.samples.ejb;
import javax.ejb.*;
import javax.naming.*;
import javax.rmi.*;
public class EmployeeFacadeBean implements SessionBean {
SessionContext sessionContext;
public void ejbCreate() throws CreateException {
/**@todo Complete this method*/
}
public void ejbRemove() {
/**@todo Complete this method*/
}
public void ejbActivate() {
/**@todo Complete this method*/
}
public void ejbPassivate() {
/**@todo Complete this method*/
}
public void setSessionContext(SessionContext sessionContext) {
this.sessionContext = sessionContext;
}
public java.lang.String getEmployeeFirstName(java.lang.Short empNo) {
try {
//get naming context
Context ctx = new InitialContext();
//look up jndi name
Object ref = ctx.lookup("java:comp/env/ejb/employee");
//cast to Home interface
EmployeeHome employeeHome = (EmployeeHome) PortableRemoteObject.narrow(ref, EmployeeHome.class);
Employee employee = employeeHome.findByPrimaryKey(empNo);
return employee.getLastName();
}
catch(Exception e) {
e.printStackTrace();
}
return null;
}
}
Listing 9 Client Testing the Session Façade, Which in Turn
Accesses the Employee Entity Bean (EmployeeFacadeTestClient.java)
package testclient;
import com.sams.samples.ejb.*;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;
/**
* <p>Title: Session Facade Test Client</p>
* <p>Description: Testing the entity beans local interface via the session</p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: SAMS Publishing</p>
* @author unascribed
* @version 1.0
*/
public class EmployeeFacadeTestClient {
static final private String ERROR_NULL_REMOTE = "Remote interface reference is null. It must be created by calling one of the Home interface methods first.";
static final private int MAX_OUTPUT_LINE_LENGTH = 100;
private boolean logging = true;
private EmployeeFacadeHome employeeFacadeHome = null;
private EmployeeFacade employeeFacade = null;
//Construct the EJB test client
public EmployeeFacadeTestClient() {
long startTime = 0;
if (logging) {
log("Initializing bean access.");
startTime = System.currentTimeMillis();
}
try {
//get naming context
Context ctx = new InitialContext();
//look up jndi name
Object ref = ctx.lookup("EmployeeFacade");
//cast to Home interface
employeeFacadeHome = (EmployeeFacadeHome) PortableRemoteObject.narrow(ref, EmployeeFacadeHome.class);
if (logging) {
long endTime = System.currentTimeMillis();
log("Succeeded initializing bean access.");
log("Execution time: " + (endTime - startTime) + " ms.");
}
java.lang.Short empNo = new java.lang.Short("5");
EmployeeFacade employeeFacade = this.create();
System.out.println(employeeFacade.getEmployeeFirstName(empNo));
}
catch(Exception e) {
if (logging) {
log("Failed initializing bean access.");
}
e.printStackTrace();
}
}
//-----------------------------------------------------------------------
// Methods that use Home interface methods to generate a Remote interface
// reference
//-----------------------------------------------------------------------
public EmployeeFacade create() {
long startTime = 0;
if (logging) {
log("Calling create()");
startTime = System.currentTimeMillis();
}
try {
employeeFacade = employeeFacadeHome.create();
if (logging) {
long endTime = System.currentTimeMillis();
log("Succeeded: create()");
log("Execution time: " + (endTime - startTime) + " ms.");
}
}
catch(Exception e) {
if (logging) {
log("Failed: create()");
}
e.printStackTrace();
}
if (logging) {
log("Return value from create(): " + employeeFacade + ".");
}
return employeeFacade;
}
//-----------------------------------------------------------------------
// Methods that use Remote interface methods to access data through the bean
//-----------------------------------------------------------------------
public String getEmployeeFirstName(Short empNo) {
String returnValue = "";
if (employeeFacade == null) {
System.out.println("Error in getEmployeeFirstName(): " + ERROR_NULL_REMOTE);
return returnValue;
}
long startTime = 0;
if (logging) {
log("Calling getEmployeeFirstName(" + empNo + ")");
startTime = System.currentTimeMillis();
}
try {
returnValue = employeeFacade.getEmployeeFirstName(empNo);
if (logging) {
long endTime = System.currentTimeMillis();
log("Succeeded: getEmployeeFirstName(" + empNo + ")");
log("Execution time: " + (endTime - startTime) + " ms.");
}
}
catch(Exception e) {
if (logging) {
log("Failed: getEmployeeFirstName(" + empNo + ")");
}
e.printStackTrace();
}
if (logging) {
log("Return value from getEmployeeFirstName(" + empNo + "): " + returnValue + ".");
}
return returnValue;
}
public void testRemoteCallsWithDefaultArguments() {
if (employeeFacade == null) {
System.out.println("Error in testRemoteCallsWithDefaultArguments(): " + ERROR_NULL_REMOTE);
return ;
}
getEmployeeFirstName(null);
}
//-----------------------------------------------------------------------
// Utility Methods
//-----------------------------------------------------------------------
private void log(String message) {
if (message == null) {
System.out.println("-- null");
return ;
}
if (message.length() > MAX_OUTPUT_LINE_LENGTH) {
System.out.println("-- " + message.substring(0, MAX_OUTPUT_LINE_LENGTH) + " ...");
}
else {
System.out.println("-- " + message);
}
}
//Main method
public static void main(String[] args) {
EmployeeFacadeTestClient client = new EmployeeFacadeTestClient();
// Use the client object to call one of the Home interface wrappers
// above, to create a Remote interface reference to the bean.
// If the return value is of the Remote interface type, you can use it
// to access the remote interface methods. You can also just use the
// client object to call the Remote interface wrappers.
}
}
Building Entity Beans with JBuilder
You may look at the amount of code you need to accomplish a simple task,
but JBuilder offers a number of time-saving features to make this process
efficient. These features offer a number of capabilities regardless of the
EJB vendor you are using. The following are some of those features:
-
EJB Designer to build session and entity beans graphically
-
Component packaging for deployment
-
Deployment Descriptor Editors
-
Wizards to automatically produce container managed persistence
-
Test client generators
Many of these features were discussed in Chapter 22, "Developing Session
Beans." We will concentrate on the ones that specialize in entity beans.
We will build the same example we built earlier to access our Employee
entity and wrap the access with a session façade.
-
Create a project by choosing File, New Project from the menu. Call
the project EntityBeanSample. After you create the project, make sure
that the enterprise server is selected using the Project Properties
Editor. If you set it as the default for all projects, it will not need
to be set.
-
Create a new EJB module called EntityBean. Make sure the version property
is set to EJB 2.0 compliant.
-
Double-click on the new EJB module node. This loads the EJB Designer.
-
Right-click on the data sources in the button on the left pane of the
IDE and select Import Schema from Database. This process loads all the
information from an existing data structure, as shown in Figure
4.
Figure 4
Import data source definition from external database.
-
Fill in the connection information to your data source. In this case,
use the employee jDatastore database that ships with JBuilder.
This process loads the entire schema from the specified database. This
is accomplished by clicking on the Choose Existing Connection button.
-
Right-click on the table Employee and create a CMP 2.0 Entity Bean.
This creates an entity bean configured to manage the persistence of
the entity to the Employee table.
-
Now place both a local and remote interface on the new entity bean.
This is accomplished by selecting the bean in the Designer, and then
changing the interface's property to local/remote.
Let's look at what was generated by JBuilder and make sure that
you understand the purpose of each generated file (see Table 1).
Table 1 Files Generated when Creating a CMP Entity Bean
Filename
|
Scope
|
Description
|
Employee.java
|
Local
|
Interface for providing the accessors and mutators to the attributes
|
EmployeeHome.java
|
Local
|
Home interface for creating, finding, and removing an entity
|
EmployeeBean.java
|
Local/remote
|
Implementation class for CMP beans
|
EmployeeRemote.java
|
Remote
|
Interface for providing the accessors and mutators to the attributes
for remote usage
|
EmployeeRemoteHome.java
|
Remote
|
Home interface for creating, finding, and removing an entity for
remote usage
|
-
Compile your application to create a JAR for your EJB entity beans.
-
Add to the project a test client generated for our new Employee
entity bean, or write your own client as seen in Listing 10.
Listing 10 Test Client to Verify Your Entity Bean Operations
public EmployeeTestClient() {
long startTime = 0;
if (logging) {
log("Initializing bean access.");
startTime = System.currentTimeMillis();
}
try {
//get naming context
Context ctx = new InitialContext();
//look up jndi name
Object ref = ctx.lookup("EmployeeRemote");
//cast to Home interface
employeeRemoteHome = (EmployeeRemoteHome) PortableRemoteObject.narrow(ref, EmployeeRemoteHome.class);
if (logging) {
long endTime = System.currentTimeMillis();
log("Succeeded initializing bean access.");
log("Execution time: " + (endTime - startTime) + " ms.");
}
/* Test your component Interface */
this.findByPrimaryKey(new java.lang.Short("5"));
this.getEmpNo();
}
catch(Exception e) {
if (logging) {
log("Failed initializing bean access.");
}
e.printStackTrace();
}
}
-
Choose Tools, Borland Enterprise Server Management Agent from the menu.
-
Right-click and run either your JAR file or your EAR. This launches
a version of the enterprise server inside JBuilder.
-
Run your test application and verify the exercising of the entity bean
(see Listing 11).
Listing 11 Results of the Test Client Exercising Your Beans Methods
-- Initializing bean access.
-- Succeeded initializing bean access.
-- Execution time: 2944 ms.
-- Calling findByPrimaryKey(5)
-- Succeeded: findByPrimaryKey(5)
-- Execution time: 1452 ms.
-- Return value from findByPrimaryKey(5): Stub[repository_id=RMI:entitybeansample.EmployeeRemote:000000 ...
-- Calling getEmpNo()
-- Succeeded: getEmpNo()
-- Execution time: 40 ms.
-- Return value from getEmpNo(): 5.
About the Authors
Saleem Siddiqui is a technical architect and trainer with Dunn Solutions Group. He is also a Sun Certified Developer and a Borland Certified JBuilder Instructor. At Dunn, he provides consulting services and business application development.
Michael Landy is Director of Business Applications for Dunn Solutions Group directing the strategic solutions for clients.
Jeff Swisher is a technical manager for the Dunn Solutions Group business applications. He works as a programmer, trainer, architect, and instructional designer. He is a Sun Certified Java Developer and a Borland Certified Instructor in JBuilder.
Source of this material
 |
This material is from Chapter 23: Developing Entity Beans from the book JBuilder Developer's Guide (ISBN: 0-672-32427-X) written by Saleem Siddiqui, Michael Landy, and Jeff Swisher, published by Sams Publishing.
© Copyright Sams Publishing. All rights reserved. |
To access the full Table of Contents for the book.
Other Chapters from Sams Publishing:
Web Services and Flows (WSFL)
Overview of JXTA
Introduction to EJBs
Processing Speech with Java
The Java Database Control in BEA Weblogic
Databases and Tomcat
Working with JAX-RPC
Understanding Servlets