Developing Entity Beans

Target Audience and Content

The target audience for this guide is the Enterprise Bean provider, i.e. the person in charge of developing the software components on the server side, and more especially the Entity Beans.

The content of this guide is the following:

  1. Target Audience and content
  2. Introduction
  3. The Home Interface
  4. The Component Interface
  5. The Primary Key Class
  6. The Enterprise Bean Class
  7. Writing Database Access Operations (bean-managed persistence)
  8. Configuring Database Access for Container-managed Persistence
  9. Tuning Container for Entity Bean Optimizations

Introduction

An Entity Bean is composed of the following parts, that are to be developed by the Enterprise Bean Provider: Note that, according to the EJB 2.0 specification, the couple "Component Interface and Home Interface" may be either local or remote. Local Interfaces (Home and Component) are to be used by a client running in the same JVM as the EJB component. Create and finder methods of a local (resp. remote) home interface return local (resp. remote) component interfaces. An EJB component may have both remote and local interfaces, even if typically only one kind of interfaces is provided. If an entity bean is the target of a container-managed relationship (Cf. EJB 2.0 persistence), then it must have local interfaces.

The description of these elements is provided in the following sections.

Note: in this documentation, the term "Bean" always means "Enterprise Bean".

An entity bean represents persistent data. It is an object view of an entity stored in a relational database. The persistence of an entity bean may be handled in two ways:

Currently, the platform handles persistence in relational storage systems through the JDBC interface. For both container-managed or bean-managed persistence, JDBC connections are obtained from an object provided at the EJB server level, the DataSource. The DataSource interface is defined in the JDBC 2.0 standard extensions. A DataSource object identifies a database and a means to access it via JDBC (a JDBC driver). An EJB server may propose access to several databases and thus provides the corresponding DataSource objects. DataSources are described in more details in the section "Configuring JDBC DataSources".

The Home Interface

In addition to "home business methods", the Home interface is used by any client application to create, remove and retrieve instances of the entity bean. The bean provider only needs to provide the desired interface, the container will automatically provide the implementation. The interface must extend the javax.ejb.EJBHome interface if it is remote or the javax.ejb.EJBLocalHome interface if it is local. The methods of a remote home interface must follow the rules for java RMI. The signatures of the "create" and "find..." methods should match the signatures of the "ejbCreate" and "ejbFind..." methods that will be provided later in the enterprise bean implementation class (same number and types of arguments, but different return types).

create methods:

remove methods: finder methods:

Finder methods are used to search for an EJB object or a collection of EJB objects. The arguments of the method are used by the entity bean implementation to locate the requested entity objects. In case of bean-managed persistence, the bean provider is responsible for developing the corresponding ejbFinder methods in the bean implementation. In case of container-managed persistence, the bean provider does not write these methods, they are generated at deployment time by the platform tools; the description of the method is provided in the deployment descriptor, as defined in section "Configuring database access for container-managed persistence". In the Home interface, the finder methods must follow the rules below:

At least one of these methods is mandatory, findByPrimaryKey, which takes as argument a primary key value and returns the corresponding EJB object.

home methods:

Example

The Account bean example, provided with the platform examples will be used to illustrate these concepts. The state of an entity bean instance is stored into a relational database where the following table should exist if CMP 1.1 is used:

create table ACCOUNT (ACCNO integer primary key, CUSTOMER varchar(30), BALANCE number(15,4));

public interface AccountHome extends EJBHome {

    public Account create(int accno, String customer, double balance)
        throws RemoteException, CreateException;

    public Account findByPrimaryKey(Integer pk)
        throws RemoteException, FinderException;

    public Account findByNumber(int accno)
        throws RemoteException, FinderException;

    public Enumeration findLargeAccounts(double val)
        throws RemoteException, FinderException;
}

The Component Interface

Business methods:

The Component Interface is the client's view of an instance of the entity bean. It is what is returned to the client by the Home interface after creating or finding an entity bean instance. This interface contains the business methods of the enterprise bean. The interface must extend the javax.ejb.EJBObject interface if it is remote or the javax.ejb.EJBLocalObject if it is local. The methods of a remote component interface must follow the rules for java RMI. For each method defined in this component interface, there must be a matching method of the bean implementation class (same arguments number and types, same return type, same exceptions except for RemoteException).

Example

public interface Account extends EJBObject {
    public double getBalance() throws RemoteException;
    public void setBalance(double d) throws RemoteException;
    public String getCustomer() throws RemoteException;
    public void setCustomer(String c) throws RemoteException;
    public int getNumber() throws RemoteException;
}

The Primary Key Class

The Primary Key class is necessary for entity beans only. It encapsulates the fields representing the primary key of an entity bean in a single object. If the primary key in the database table is composed of a single column with a basic data type, the simplest way to define the primary key in the bean is to use a standard java class like java.lang.Integer or java.lang.String for example. This must be the type of a field in the bean class. It is not possible to define it as a primitive field (like int, float or boolean for example). Then, the single thing to do is to specify in the deployment descriptor the type of the primary key :
      <prim-key-class>java.lang.Integer</prim-key-class>
And in case of container-managed persistence, the field which represents the primary key
      <primkey-field>accno</primkey-field>
The other way is to define its own Primary Key class, as defined here after:

The class must be serializable, and must provide suitable implementation of the hashcode() and equals(Object) methods.

For container-managed persistence, the following rules must be followed:

Example

public class AccountBeanPK implements java.io.Serializable {
public int accno;

public AccountBeanPK(int accno) { this.accno = accno; }

public AccountBeanPK() { }

public int hashcode() { return accno; }
public boolean equals(Object other) {
...
}
}

Special case : Automatic generation of Integer primary keys field

For a CMP 2.0 and CMP1 entity bean, the jonas specific deployment descriptor contains an additional optional element,  automatic-pk, which may have one the following value : true or false (default value).
If you choose true the primary key field's value of your bean is automatically generated by the container when the entity bean is created. You must choose primary type java.lang.Integer for your primary key's field
into <prim-key-class> tag, and not initialize value of this field in your ejbCreate method.

Example of using new element :

JOnAS specific deployment descriptor :
 <jonas-entity>
    <ejb-name>AddressEJB</ejb-name>
    <jdbc-mapping>
        <jndi-name>jdbc_1</jndi-name>
        <automatic-pk>true</automatic-pk>
    </jdbc-mapping>
 </jonas-entity>

Standard deployment descriptor :
  <entity>
      <ejb-name>AddressEJB</ejb-name>
      <local-home>com.titan.address.AddressHomeLocal</local-home>
      <local>com.titan.address.AddressLocal</local>
      <ejb-class>com.titan.address.AddressBean</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>java.lang.Integer</prim-key-class>
      <reentrant>False</reentrant>
      <cmp-version>2.x</cmp-version>
      <abstract-schema-name>Cmp2_Address</abstract-schema-name>
      <cmp-field><field-name>id</field-name></cmp-field>
      <cmp-field><field-name>street</field-name></cmp-field>
      <cmp-field><field-name>city</field-name></cmp-field>
      <cmp-field><field-name>state</field-name></cmp-field>
      <cmp-field><field-name>zip</field-name></cmp-field>
      <primkey-field>id</primkey-field>

Address Bean Class:
   // Field Id is not initialized during ejbCreate methode
   public Integer ejbCreateAddress(String street, String city, String state,  String zip ) throws javax.ejb.CreateException {
       setStreet(street);
       setCity(city);
       setState(state);
       setZip(zip);
       return null;
    }

The Enterprise Bean Class

The EJB implementation class implements the bean's business methods of the component interface, and the methods dedicated to the EJB environment, the interface of which are explicitely defined in the EJB specification. The class must implement the javax.ejb.EntityBean interface, must be defined as public, may not be abstract in case of CMP 1.1, and must be abstract in case of CMP 2.0 (in this case, the abstract methods are the get and set accessor methods of the bean cmp and cmr fields). The EJB environment dedicated methods that the EJB provider must develop are listed below.

The first set of methods are those corresponding to the create and find methods of the Home interface: