Container-Managed Persistence 1.1


Container-Managed Persistence 1.1

The EJB specifications 2.0/2.1 have retained container-managed persistence from version 1.1 for the sake of backward compatibility. Existing entity bean applications can thus be migrated stepwise to version 2.0/2.1. The changes in version 2.0/2.1 in the area of container-managed persistence are rather extensive and have many advantages over version 1.1. Above all, this includes persistent relationships and the local client view. For the development of new applications and application modules in which persistence plays a role, CMP entity beans according to version 2.0 should certainly be used.

Overview

Figure 5-18 gives a complete overview of the classes and interfaces of entity beans with container-managed persistence of version 1.1. An EJB 1.1 entity bean is limited to the use of the remote client view. It can have neither a local home interface nor a local interface. Moreover, with EJB 1.1 entity beans there are no home methods and no select methods.

click to expand
Figure 5-18: Remote interfaces and classes of the CMP entity bean (EJB 1.1).

On the right in Figure 5-18 can be found the entity bean classes. Instances of this class are managed at run time through the EJB container. On the left side can be seen the interfaces that are available to the client and are implemented by the home or remote object of the EJB container (see also Chapter 3).

Every entity bean class implements the interface javax.ejb.EntityBean. In contrast to EJB 2.0 entity beans, the bean class of an EJB 1.1 entity bean is a concrete class. All public attributes of the class are persistent by definition even though they are also defined in the deployment descriptor as persistent attributes. In the entity bean class the bean developer implements the actual functionality of the bean.

On the left in Figure 5-18 are the classes for the bean's primary key. Since objects of this class are transported across the network between server and client, the class must be serializable. It implements the interface java.io.Serializable. All persistent attributes of the entity bean class that belong to the primary key are brought over by the bean developer into the primary key class. The name and data type of these attributes are identical in both the entity bean class and the primary key.

The components of the entity bean class can be arranged in four groups:

  • Attributes;

  • State management;

  • Identity management;

  • Application logic.

In the rest of this section we will look at the individual components in detail.

Attributes

Every persistent attribute is defined in the (concrete) bean class as a member variable. The persistent attributes must be public, and may not be final, since otherwise, they cannot be modified by the EJB container. They may have the following data types:

  • primitive data types of the programming language Java (int, float, long, etc.);

  • serializable data types of the programming language Java (including, in particular, java.lang.String, java.lang.Integer);

  • references to the remote or home interface of other Enterprise Beans.

Listing 5-46 shows an example of how an EJB 1.1 entity bean defines persistent attributes in the bean class.

Listing 5-46: Persistent attributes of an EJB 1.1 entity bean.

start example
public class AddressBean implements EntityBean {

    public String name;
    public String firstName;
    public String street;
    public int postalCode;
    public String city;
    ...
}
 
end example

Finally, the attributes become persistent only when they are declared thus in the deployment descriptor. Listing 5-47 shows how the persistent attributes from Listing 5-46 are declared in the deployment descriptor.

Listing 5-47: Deployment descriptor of an EJB 1.1 entity bean.

start example
...
  <enterprise-beans>
    <entity>
      <ejb-name>Address</ejb-name>
      <home>AddressHome</home>
      <remote>Address</remote>
      <ejb-class>AddressBean</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>java.lang.String</prim-key-class>
      <reentrant>False</reentrant>
      <cmp-version>1.x</cmp-version>
      <cmp-field>
        <field-name>name</field-name>
      </cmp-field>
      <cmp-field>
        <field-name>firstName</field-name>
      </cmp-field>
      <cmp-field>
        <field-name>street</field-name>
      </cmp-field>
      <cmp-field>
        <field-name>postalCode</field-name>
      </cmp-field>
      <cmp-field>
         <field-name>city</field-name>
      </cmp-field>
      <primkey-field>name</primkey-field>
    </entity>
  </enterprise-beans>
...
 
end example

With EJB 1.1 entity beans the value 1.x is entered in the element cmp-version. With EJB 1.1 entity beans there do not exist the elements abstract-schema-name and query. Otherwise, the instructions are largely identical to those for EJB 2.0/2.1 entity beans.

The EJB container is responsible for the initialization and synchronization of persistent attributes with the persistence medium. The attributes can be read and write accessed by the entity bean's application methods (those that are called by the client).

State Management

The methods of state management (see Figure 5-18) are the callback methods, which are called by the EJB container in order to inform the entity bean about a change of state. The individual states and state transitions are displayed in Figure 5-6. The methods have the same function as with EJB 2.0 entity beans, and so we shall go into them here only briefly.

void setEntityContext(EntityContext ctx)

The method setEntiyContext is called by the EJB container when a bean instance is generated and is transformed into the state Pooled. Its function is the initialization of the bean. The EJB container transfers to the entity bean its EntityContext. During this method the EntityContext object should be stored as a variable.

void unsetEntityContext()

This method is called by the EJB container when it no longer needs a bean instance and wants to remove it from the pool. The call informs the bean instance that its associated EntityContext is invalid.

void ejbActivate()

The EJB container calls this method to inform an entity bean instance that it has received a particular identity. In the entity context the primary key can now be queried. The bean instance is transformed into the state Ready-Async.

void ejbPassivate()

This method is the complement of ejbActivate. It is called by the EJB container when a bean instance changes from the state Ready to the state Pooled. The bean instance then no longer possesses a bean identity.

void ejbLoad()

With a call to this method the EJB container informs the bean instance that it has newly provided the bean with persistent attributes. This is necessary in the case in which the bean has not yet been initialized or if the database content has been changed through parallel access. The EJB container can synchronize the bean at any time in the state Ready. This often happens before a method of the application logic is called. The bean changes from the state Ready-Async into the state Ready-Sync.

For example, this method can be used by the entity bean to recalculate transient variables from persistent variables recently synchronized with the persistence medium.

void ejbStore()

Through a call to this method the EJB container informs a bean instance that it will write the bean's persistent attributes into the persistence system. The bean instance changes from the state Ready-Sync into the state Ready-Update.

Identity Management

The methods for identity management form the second group of methods displayed in Figure 5-18. They enable the generation, deletion, and searching of entity bean identities. These methods are also found in the home interface and are available to the client before it has a bean instance.

ejbFind<name>(<args>)

In this group there are one or more search methods. The methods are defined in the home interface. A search method can target either a single entity bean or a set of them. The search methods for entity beans begin with the prefix find. Each entity bean must define at least one method findByPrimaryKey with the primary key as sole parameter. The remaining finder methods can have arbitrary signatures. The finder methods are neither declared nor implemented in the bean class, but are generated by the EJB container (the various ejbFind methods in the bean classes of Figure 5-18 are indicated in a slant font). The findByPrimaryKey method for generation is not otherwise complex. For the remaining finder methods instructions must be given in the form of search queries. As mentioned already, EJB 1.1 knows nothing about EJB-QL. The formulation of such queries therefore depends on what is offered by the application server. This state of affairs limits the ease of portability of EJB 1.1 entity beans.

<primKeyClass> ejbCreate(<args>)

For the generation of beans there are one or more methods, all of which are called ejbCreate and define the bean's primary key class as return value. The methods are distinguished by their parameters, and can otherwise be defined according to the wishes of the developer. These methods are not part of the entity bean interface, since the parameter types and return value types differ for each bean class.

These methods are available to the client and are therefore also declared in the home interface. The signatures of the create methods in the home interface (create) and in the bean class (ejbCreate) are distinguished by their return values. The methods in the home interface have the bean's remote interface as return value. The methods of the bean class use the primary key. The EJB container manages the required conversion. The implementation of this method uses parameters to initialize the persistent attributes of the entity bean. As result, null is always returned.

void ejbPostCreate(<args>)

For every ejbCreate method the bean developer must define an ejbPostCreate method with the same parameter types. The ejbPostCreate method is always executed by the EJB container according to the corresponding ejbCreate method with the identical transaction context (see Chapter 7 for details).

Additional initialization steps can be executed in these methods. The bean identity is available to these methods, in contrast to the ejbCreate methods.

With the execution of ejbCreate and ejbPostCreate the bean instance changes from the state Pooled to the state Ready-Update. However, the new bean identity is frequently stored in the database only after the subsequent execution of the method ejbStore.

void ejbRemove()

For management of bean identities one also has methods for deleting beans. The client issues the command to delete an entity bean identity by a call to the method remove in the home or remote interface. The method ejbRemove of the bean instance is, however, called by the EJB container, which transmits the client's call.

The bean instance is simply informed of its impending state change. The EJB container takes care of deletion of data. Frequently, additional resources must be freed in a call to this method before the bean instance changes into the state Pooled.

Like ejbPassivate, this method is called when the state of a bean instance changes from Ready to Pooled. However, here the bean identity is deleted. After the call the bean instance no longer has an identity. Any reserved resources must be released before the bean instance changes into the state Pooled. The method ejbPassivate is not called in this state transition.

Application Logic

The fourth group of methods consists of those for the application logic, which are located in the remote interface. These methods are implemented by the bean developer in the bean class. The definition in the bean class has the same signature as in the definition in the remote interface. As a rule, with these methods read and write access will be made to the persistent attributes.