Geronimo_MoinMoin_wiki > Working_with_Enterprise_JavaBeans
Added by Confluence Administrator, last edited by Confluence Administrator on Aug 02, 2006

Contents

About

This page describes the OpenEJB-specific configurations required to deploy EJB onto Geronimo.

CMP Entity Beans

This section assumes that you:

Database Configuration

The CMP engine gains access to the database used to store the entity beans via the connection factory identified by the <cmp-connection-factory> element. This latter is a "generic" element providing enough information to identify a JDBC data source already deployed or being deployed along with the CMP entity beans.

The following snippet illustrates a typical usage of the <cmp-connection-factory> element, where the out-of-the-box connection factory, and hence database, is used.

Snippet #1 â€" Defining a connection factory

    ...
    <cmp-connection-factory>
        <application>null</application>
        <module>org/apache/geronimo/DefaultDatabase</module>
        <name>DefaultDatasource</name>
    </cmp-connection-factory>
    ...

Database Mapping

CMP Fields

An entity bean is mapped to a single table via the <table-name> element. Its persistent fields are mapped to the columns of this same table via the <cmp-field-mapping> elements.

The following snippet illustrates the usage of both of these elements, where:

  • the entity bean BeanA is mapped to the table A
  • its field field1 is mapped to the column a1.

Snippet #2 â€" Mapping an entity bean to a table and its fields to some table columns

    ...
    <ejb-name>BeanA</ejb-name>
    <table-name>A</table-name>
    <cmp-field-mapping>
        <cmp-field-name>field1</cmp-field-name>
        <table-column>a1</table-column>
    </cmp-field-mapping>
    ...

The above configuration is the simplest one and should work in most cases as long as the data type conversion between the Java type of field1 and the SQL one of a1 can be carried out properly as per the JDBC specifications. In all the other cases, for instance where field1 is a byte[] and a1 is a BLOB, two optional elements may be used in conjunction to control explicitly the SQL type to use and how to perform the conversion between the type of field1 and the one of a1. These two optional elements are: <sql-type>, a SQL type identifier, which must be the name of a field declared by the java.sql.Types class; and <type-converter>, the full class name of a org.tranql.sql.Type**Converter implementation.

The org.tranql.sql.Type*Converter type defines two contracts: convertJavaToSQLType() which is used to convert Java types to SQL types and convertSQLToJava*Type() to realize the inverse operation.

The following code depicts how these two elements could be used to force field1 to be marshalled into a BLOB column.

Snippet #3 â€" Controlling explicitly the storage of a CMP field

    ...
    <cmp-field-mapping>
        <cmp-field-name>field1</cmp-field-name>
        <table-column>a1</table-column>
        <sql-type>BLOB</sql-type>
        <type-converter>org.tranql.sql.typeconverter.SerializableConverter</type-converter>
    </cmp-field-mapping>
    ...

A likely scenario where this feature could be used is where field1 having the type byte[] is to be stored "as is" into a BLOB column. In such a case, a Type*Converter wrapping the byte array into an Input*Stream would have to be implemented.

Even if these two optional elements have been presented as tightly related, they can be used independently, if required.

Nota bene: in the simplest scenario illustrated by the Snippet #2 and where the type of field1 is not explicitely mapped to a SQL type by TranQL, the implementation assumes that field1 is to be serialized into a BLOB. This implies that Dependent Value Classes are stored by default into BLOB columns.

Relationships

The database mapping of relationships mirrors the structure defined by the standard ejb-jar.xml deployment descriptor.

One-To-One

The configuration of such a relationship requires the mapping of one and only one CMR field of the two related entity beans. The identification of the mapped CMR field is achieved via the relationship-role-source and cmr-field elements. The mapping per se is provided via the role-mapping element. This latter is a collection of cmr-field-mapping elements specifying the mapping between the columns of the two tables associated to the related entity beans. More accurately, its key-column sub-element identifies a column associated to a CMP field of the source entity bean. Note that this CMP field must store either the primary key or, in the case of compound primary keys, a part of it. The foreign-key-column sub-element indicates the associated foreign key column. This foreign key column is defined by the underlying table of the related entity bean.

The following snippet sketches the configuration of an OTO relationship for the CMR field b of an entity bean A. This bean has a compound primary key stored in the columns a1 and a2 of its underlying table. These latter are mapped to the columns fka1 and fka2 of the underlying table of the entity bean related to A via the CMR field b.

Snipper #4 â€" Mapping of an OTO relationship

    ...
    <relationships>
        <ejb-relation>
            <ejb-relationship-role>
                <relationship-role-source>
                    <ejb-name>A</ejb-name>
                </relationship-role-source>
                <cmr-field>
                    <cmr-field-name>b</cmr-field-name>
                </cmr-field>
                <role-mapping>
                    <cmr-field-mapping>
                        <key-column>a1</key-column>
                        <foreign-key-column>fka1</foreign-key-column>
                    </cmr-field-mapping>
                    <cmr-field-mapping>
                        <key-column>a2</key-column>
                        <foreign-key-column>fka2</foreign-key-column>
                    </cmr-field-mapping>
                </role-mapping>
            </ejb-relationship-role>
        </ejb-relation>    
    </relationships>
    ...

In the case of uni-directional relationships where the only CMR field is defined by the entity bean whose underlying table holds the foreign key attributes, the above snippet needs to be amended by the foreign-key-column-on-source optional element. This element reverses the column mappings: the key-column sub-element identifies a column associated to a CMP field of the related entity bean; and the foreign-key-column sub-element indicates the associated foreign key column, which is defined by the underlying table of the source entity bean.

Nota bene: the mapping of relationships do not mandate the extra-configuration of optional elements of the standard ejb-jar.xml deployment descriptor. Indeed, it uses exclusively some of its mandatory elements. For instance, it does not require the configuration of ejb-relationship-role-name elements, which are optional as per the specifications.

One-To-Many

The configuration of such relationships is similar to the one of One-To-One relationship.

Many-To-Many

This cardinality requires the mapping of the two roles of the relationships. This means that two ejb-relationship-role elements must be defined. At least one of them must define a cmr-field field.

Auto-Generated Primary Key

Primary keys of entity beans can be auto-generated. This can save you the trouble of providing primary keys for entities in the create() call. This feature may also be used to deploy entity beans without a natural primary key, i.e. having a primary key class set to java.lang.Object. The configuration of auto-generated primary key entity beans requires the configuration of a key-generator element for each affected EJB.

The children of the key-generator element define the strategy to be used to auto-generate primary key instances. The provided strategies are:

  • auto-increment-table: use table generated primary keys (such as from an AUTO_INCREMENT column or trigger);
  • sequence-table: use a sequence table; and
  • sql-generator: use any SQL statements.
  • custom-generator: provide your own GBean implementing org.tranql.pkgenerator.!PrimaryKeyGenerator (elsewhere) and refer to it here

The following snippet shows how the key-generator element is to be configured:

Snippet #4 â€" Auto-generation of primary keys

    ...
    <key-generator>
      <sequence-table>
        <table-name>SOME_TABLE</table-name>
        <sequence-name>EJB_NAME</sequence-name>
        <batch-size>10</batch-size>
      </sequence-table>
    </key-generator>
    ...
    <key-generator>
      <auto-increment-table>
        <sql>INSERT INTO ENTITY_TABLE (col2, col3) VALUES (null, null)</sql>
        <return-type>java.lang.Integer</return-type>
      </auto-increment-table>
    </key-generator>
    ...
    <key-generator>
      <sql-generator>
        <sql>SELECT MY_ORACLE_SEQ.NEXTVAL FROM DUAL</sql>
        <return-type>java.lang.Integer</return-type>
      </sql-generator>
    </key-generator>
    ...
    <key-generator>
      <custom-generator>
        <generator-name>geronimo.server:name=MyCustomGeneratorName</generator-name>
        <primary-key-class>java.lang.Integer</primary-key-class>
      </custom-generator>
    </key-generator>

CMP with Unknown Primary Key

The set-up of entity beans with unknown primary key classes requires the configuration of:

  • additional CMP fields. These fields, exclusively used to hold the (auto-generated) primary keys, must use the cmp-field-class optional element. This element specifies the full class name of additional CMP fields, as this information can not be derived from the entity bean class; and
  • primary key generators for these additional fields.

Flushing Strategy

DML operations are flushed upon transaction commit. The default flushing strategy of these operations does not enforce potential foreign key constraints defined at the database level. In order to switch on the ordering of DML operations in order to respect these potential constraints, the optional element enforce-foreign-key-constraints is to be set.

Supported Configurations

Users are invited to identify hereafter the databases and their associated drivers, which have been used successfully with the CMP engine:

  • Oracle9i with Oracle10g JDBC driver. Note that Oracle10g is backward compatible and supports now properly the Prepared*Statement.setBinary*Stream() method, which is used for the storage of Dependent Value Classes.

Nota bene: the implementation requires a JDBC 3.0 compliant driver.