Container Managed Persistence API

What is the pluggable CMP mechanism?

We define a Java interface com.inprise.ejb.cmp.Manager that acts as the contract between our Container and the actual persistence mechanism. We have an implementation of this interface that uses plain JDBC to interact with the database. Every Entity Bean is associated with a Manager. Much of the information necessary to map is obtained from the deployment descriptor. This provides a basic CMP provider. Other implementations of this SPI specific to OR Tools, OODBMS, etc. can be plugged in to provide enhanced services. Using a deployment descriptor property it is possible to dynamically choose the CMP provider.
package com.inprise.ejb.cmp;

/**
 * This interface provide a Service Provider Interface for Container
 * Managed Persistence.  The SPI methods correspond to the methods
 * which are called on Entity beans.  A third party can implement this
 * SPI, to provide a container with customized CMP.
 */
public interface Manager {

  /**
   * Initialize the manager. 
   * @param primaryKeyNames The names of the primary key fields.
   * @param primaryKeyTypes The types of the primary key fields.
   * @param containerManagedNames The names of the other container 
   * managed fields, excluding the primary key fields.  
   * @param containerManagedTypes The types of the other container 
   * managed fields, excluding the primary key fields.  
   * @param properties The environment variables from the deployment
   * descriptor.
   * @exception java.rmi.RemoteException if a system failure occurs.
   */
  void init(String[] primaryKeyNames,
            Class[] primaryKeyTypes,
            String[] containerManagedNames,
            Class[] containerManagedTypes,
            java.util.Properties properties)
    throws java.rmi.RemoteException;

  /**
   * Do whatever it takes to create an entity bean. For databases, 
   * this probably means inserting a new row into a table using 
   * primary key and other container managed fields.
   * @param primaryKeyFields The values of the primary key fields.
   * @param containerManagedFields The values of the other 
   * container managed fields.  
   * @exception javax.ejb.CreateException if the entity could not be 
   * created.
   * @exception java.rmi.RemoteException if a system failure occurs.
   */
  void create(Object[] primaryKeyFields, Object[] containerManagedFields)
    throws javax.ejb.CreateException, java.rmi.RemoteException;

  /**
   * Do whatever it takes to remove an entity bean.  For databases, 
   * this probably means removing a row from a table using the 
   * primary key.
   * @param primaryKeyFields The values of the primary key fields.
   * @exception javax.ejb.RemoveException if the entity could not be 
   * removed.
   * @exception java.rmi.RemoteException if a system failure occurs.
   */
  void remove(Object[] primaryKeyFields)
    throws javax.ejb.RemoveException, java.rmi.RemoteException;

  /**
   * Verify that the primary key actually represents a valid entity.
   * For databases, this probably means verifying that a select 
   * using the primary key returns a valid result.
   * @param primaryKeyFields The values of the primary key fields.
   * @exception javax.ejb.FinderException if the primary key is 
   * invalid.
   * @exception java.rmi.RemoteException if a system failure occurs.
   */
  void findByPrimaryKey(Object[] primaryKeyFields)
    throws javax.ejb.FinderException, java.rmi.RemoteException;

  /**
   * Find the primary key corresponding to a single entity bean.
   * @param methodSignature the full signature of the Java method, 
   * including arguments names: e.g. "method(type1 arg1, type2 arg2)"
   * @param argNames the names of the arguments
   * @param argTypes the types of the arguments
   * @param args the arguments to be passed to the finder method.
   * @return an the container managed fields other than the
   * primary key fields.
   * @exception javax.ejb.FinderException if no values were 
   * found.
   * @exception java.rmi.RemoteException if a system failure occurs.
   */
  Object[] findSingle(String methodSignature,
                      String[] argNames, 
                      Class[] argTypes, 
                      Object[] args)
    throws javax.ejb.FinderException, java.rmi.RemoteException;

  /**
   * Find the primary keys corresponding to an enumeration 
   * of entity beans.
   * @param methodSignature the full signature of the Java method, 
   * including arguments names: e.g. "method(type1 arg1, type2 arg2)"
   * @param argNames the names of the arguments
   * @param argTypes the types of the arguments
   * @param args the arguments to be passed to the finder method.
   * @return an enumerations of primary key field, corresponding
   * to the results of the find.  Each element in the enumeration 
   * is an Object[] of primary key fields.
   * @exception javax.ejb.FinderException this exception is 
   * generally not thrown.
   * @exception java.rmi.RemoteException if a system failure occurs.
   */
  java.util.Enumeration findEnumeration(String methodSignature,
                                        String[] argNames, 
                                        Class[] argTypes, 
                                        Object[] args) 
    throws javax.ejb.FinderException, java.rmi.RemoteException;

  /**
   * Find the primary keys corresponding to an collection 
   * of entity beans.
   * @param methodSignature the full signature of the Java method, 
   * including arguments names: e.g. "method(type1 arg1, type2 arg2)"
   * @param argNames the names of the arguments
   * @param argTypes the types of the arguments
   * @param args the arguments to be passed to the finder method.
   * @return an collections of primary key field, corresponding
   * to the results of the find.  Each element in the collection 
   * is an Object[] of primary key fields.
   * @exception javax.ejb.FinderException this exception is 
   * generally not thrown.
   * @exception java.rmi.RemoteException if a system failure occurs.
   */
  java.util.Collection findCollection(String methodSignature,
                                      String[] argNames, 
                                      Class[] argTypes, 
                                      Object[] args) 
    throws javax.ejb.FinderException, java.rmi.RemoteException;

  /**
   * Do whatever it takes to load an entity bean.  For databases, 
   * this probably means doing a select on the primary key fields, 
   * and extracting the other container managed fields from the 
   * result.
   * @param primaryKeyFields The values of the primary key fields.
   * @return an the container managed fields other than the
   * primary key fields.
   * @exception java.rmi.RemoteException if a system failure occurs.
   */
  Object[] load(Object[] primaryKeyFields)
    throws java.rmi.RemoteException;

  /**
   * Do whatever it takes to store an entity bean.  For databases, 
   * this probably means doing an update on the primary key using 
   * the values of the container managed fields.
   * @param primaryKeyFields The values of the primary key fields.
   * @param containerManagedFields The values of the other 
   * container managed fields.  
   * @param oldContainerManagedFields The values of the other 
   * container managed fields at the beginning of the transaction.
   * @exception java.rmi.RemoteException if a system failure occurs.
   */
  void store(Object[] primaryKeyFields, 
             Object[] containerManagedFields, 
             Object[] oldContainerManagedFields)
    throws java.rmi.RemoteException;


}

How do I direct the Container to use my CMP provider?

This is done by making an entry in the XML deployment descriptor of the entity bean. Look at the custom_cmp example for a demonstration of how this is done.

Basically you need to make an entry like this in ejb-inprise.xml

<inprise-specific>
    <enterprise-beans>
        <entity>
            <ejb-name>account</ejb-name>
            <bean-home-name>account</bean-home-name>
            <property>
                <prop-name>ejb.cmp.manager</prop-name>
                <prop-type>String</prop-type>
                <prop-value>CustomPersistenceManager</prop-value>
            </property>
        </entity>
    </enterprise-beans>
</inprise-specific>
Specify the name of a class implementing the interface com.inprise.ejb.cmp.Manager. An instance of this class is used to perform CMP. This property is optional. The default implementation is com.inprise.ejb.cmp.JdbcManager, which is part of the product, and as the name implies, does CMP using JDBC.