You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by sc...@geronimo.apache.org on 2004/12/04 14:16:06 UTC

[Apache Geronimo Wiki] New: Working with Enterprise JavaBeans

   Date: 2004-12-04T05:16:06
   Editor: GiannyDamour <gd...@apache.org>
   Wiki: Apache Geronimo Wiki
   Page: Working with Enterprise JavaBeans
   URL: http://wiki.apache.org/geronimo/Working with Enterprise JavaBeans

   CMP - getting started.

New Page:

'''Contents'''
[[TableOfContents]]

= About =

This page presents from a user perspective the OpenEJB specific configurations required to get EJB up and 
running within Geronimo.

= CMP Entity Beans =

This section assumes that you:
  * know how to deploy a JDBC data source in Geronimo; and
  * know what is a GBean.

== 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''; and
  * 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 scenarii, 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: ''convert''''''Java''''''To''''''SQL''''''Type()'' which is used 
to convert Java types to SQL types and ''convert''''''SQL''''''To''''''Java''''''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 feature is used to deploy entity beans without 
a natural primary key, ''i.e.'' having a primary key class set to ''java.lang.Object''. Note that while 
this mechanism is intended to be used exclusively for such entity beans, it may also be configured to 
work with any entity beans.

The configuration of auto-generated primary key entity beans requires the definition of a G''''''Bean 
implementing the ''org.openejb.entity.cmp.pkgenerator.Primary''''''Key''''''Generator'' interface and the configuration 
of an ''automatic-key-generation'' element identifying this same G''''''Bean.

The G''''''Bean defines the strategy to be used to auto-generate primary key instances. The provided strategies 
are defined in the ''org.openejb.entity.cmp.pkgenerator'' package and are:
  * ''Auto''''''Increment''''''Table''''''Primary''''''Key''''''Generator''''''Wrapper'': use table generated primary keys;
  * ''Sequence''''''Table''''''Primary''''''Key''''''Generator''''''Wrapper'': use a sequence table; and
  * ''SQL''''''Primary''''''Key''''''Generator''''''Wrapper'': use any SQL statements.

The following snippet shows how the ''automatic-key-generation'' element is to be configured to used the 
primary key generator ''geronimo.server:role=CMPPKGenerator,name=Entity'', a G''''''Bean, which 
creates ''java.lang.Integer'' instances.

'''Snippet #4 – Auto-generation of primary keys'''
{{{
    ...
    <automatic-key-generation>
        <generator-name>geronimo.server:role=CMPPKGenerator,name=Entity</generator-name>
        <primary-key-class>java.lang.Integer</primary-key-class>
    </automatic-key-generation>
    ...
}}}

=== 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 know 
properly the ''Prepared''''''Statement.set''''''Binary''''''Stream()'' method.

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