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.