Part 1 of this article described how in WebSphereTM Application Server, Advanced Edition, 4.0, Container Managed Persistence (CMP) EJB attributes are mapped into relational database columns through a set of three XML files:
- The EJB-JAR file that describes the EJBs and their container-managed attributes.
- The schema XML file that describes the database schema that the EJB will be mapped to.
- The map XML file that describes how the attributes in the EJBs are mapped to columns in the database schema.
What that article didn't describe was anything about EJB relationships. The ability of an EJB to reference another EJB, and the ability to map those relationships to foreign keys in a relational database, was one of the key advantages of the EJB implementation in VisualAgeTM for JavaTM and WebSphere Application Server (hereafter called Application Server) 3.5. (For information on EJB associations in Application Server 3.5, see [Brown 2000].) This advantage has been improved in Application Server 4.0. and WebSphere Studio Application Developer (hereafter called Application Developer). As you can imagine from reading the preceding article, the metadata that describes these relationships is now also stored in XML files in the same way that attribute-column mappings are stored. In this article we'll explore these files and help you understand how Application Developer and Application Server 4.0 work.
However, before we look at the details of the files in Application Server 4.0, we need to take a detour into the EJB 2.0 specification. While we're there, you'll pick up some concepts that will help you understand how relationships are implemented in Application Server 4.0. It only implements the EJB 1.1 specification, but it also implements many of the ideas from EJB 2.0 in a compatible form.
Probably the biggest news on the J2EE front this past year was the release of the EJB 2.0 Final Release 2 specification [Sun]. Those of you who don't follow Sun's specification releases as closely as you follow your favorite sports scores are probably shaking your head about now and asking, "Why was it called Final Release 2? Wasn't the first 'Final Release' final enough?" Well, there's some history here that bears on our story.
The first "final release" of the EJB 2.0 specification (as well as the previous drafts of the 2.0 specification) introduced a peculiar dichotomy into the world of EJBs. The dichotomy had to deal with the difference between EJBs and a special breed of creatures called dependent objects . The first time that Sun released the specification, the suggestion to the vendors was to discourage object-to-object relationships among Entity beans. Instead, object-to-object relationships, like the standard example of a Customer having a relationship to an Address as in Figure 1 below, were to be implemented using a different set of classes called dependent objects. This wasn't entirely a bad idea -- a major reason for this design was that because dependent objects were to be local (and not distributed like EJBs), it would in theory be possible for container vendors to build some "intelligence" into the container. The container could then do caching and intelligent management of these objects in ways that can't be done with EJBs, since a client to an EJB can't know if the EJB is local to its address space, or located in some other EJB container out on the network.
Figure 1. Simple 1-1 relationship
When the specification was previewed by different application server vendors, they discovered that this wasn't an optimal way to represent relationships. Not only was it complex for developers to understand, it was also quite challenging for the vendors to implement. So the vendors asked for a revision from Sun. After a number of meetings and e-mails, some old ideas were dusted off and reexamined. The result of this flurry of activity was a significant simplification of the specification. Dependent objects were dropped, and EJB-to-EJB relationships were reintroduced.
In the final EJB 2.0 specification, EJBs are related to each other through a simple set of relationship declarations in the EJB deployment descriptor (EJB DD). The code to handle the relationships is generated by the container in the EJB implementations, so that other EJBs can traverse and manipulate the relationships. The key to gaining the performance advantages of locality would be through a new way of deploying EJBs: in EJB 2.0 they can be deployed either as remote or as local EJBs. If an EJB is local, a vendor can use the same type of optimizations that would have been possible for dependent objects, but without changing the underlying programming model . This last point cannot be emphasized enough. The single, unified programming model and abstract XML description of all EJBs (local or remote) is at the heart of the EJB 2.0 specification.
This point brings us back to our main story. The EJB 2.0 specification says that entity EJBs can be related to each other, and that the relationships are described in the EJB 2.0 DD. How does this look in the EJB 2.0 specification? Let's look at the following excerpt from a DD for our simple Customer-Address example described above.
Listing 1.
<ejb-jar>
...
<enterprise-beans>
<entity>
<ejb-name>Customer</ejb-name>
<local-home>com.ibm.ejb.CustomerLocalHome</local-home>
<local>com.ibm.ejb.CustomerLocal</local>
¦
</entity>
<entity>
<ejb-name>Address</ejb-name>
<local-home>com.titan.address.AddressLocalHome</local-home>
<local>com.titan.address.AddressLocal</local>
¦
</entity>
¦
</enterprise-beans>
<relationships>
<ejb-relation>
<ejb-relation-name>Customer-Address</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>
Customer-For
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>Customer</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>homeAddress</cmr-field-name>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>
Address-of
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>Address</ejb-name>
</relationship-role-source>
</ejb-relationship-role>
</ejb-relation>
<relationships>
|
(This example has been adapted from Enterprise JavaBeansTM, 3rd Edition , by Richard Monson-Haefel, which describes this example in much more detail. The book also has an excellent treatment of the EJB 2.0 specification and the way EJB 2.0 relationships operate).
Leaving aside much of the complexity of the EJB 2.0 implementation (described in [Monson-Haefel]), there are a few key points about the way the relationship between Customer and Address is represented in this DD that we need to examine.
The
<enterprise-beans>
section defines of two EJBs named Customer and Address and describes their home and local interfaces. (These two EJBs are local -- again, for more information see [Monson-Haefel].) The more interesting section is the
<relationships>
section, and particularly the single
<ejb-relation>
sample. The EJB relationship contains some particular points that you need to understand:
- Each named relationship between two EJBs contains two roles .
-
Each role has a
name
, a
multiplicity
, and a
source
, which refers back up to an EJB in the
<enterprise-beans>section. -
Roles may contain a
<cmr-field>, which is a special field added to the EJB in addition to the<cmp-field>, a container-managed field that is a regular persistent field of the EJB. If a<cmr-field>tag is present in a role, then the relationship is traversable from the EJB on that end to the EJBs on the other end of the relationship.
For those of you who prefer visual representations, Figure 2 below shows how the different sections of the
ejb-jar.xml
file relate to each other.
Figure 2. EJB 2.0 relationship definitions
Implementation of relationships in WebSphere Application Server 4.0
So where does this leave us in Application Server 4.0, since it only implements the EJB 1.1 specification and not EJB 2.0? The Application Server and Application Developer development teams decided to take a route that is architecturally compatible with EJB 2.0 (making it easier for us to write conversion tooling later) while staying within the restrictions of EJB 1.1. We had to provide a way to represent the relationship metadata mandated by EJB 2.0, but we couldn't do it within the EJB 1.1 XML DD, because the specification forbids the addition of new sections. To contain this kind of information, we added a fifth file to the "tale of four files" described in the previous article. This file, often called the
EJB extensions file
, is named
ibm-ejb-ext.xml
, and it contains three kinds of information beyond the confines of the EJB 1.1 specification:
- Associations, including the same type of role and multiplicity information described in the EJB 2.0 DD.
- Access flags for read-only getter methods, to ensure that Entity EJB instances aren't marked as dirty and persisted into the database unnecessarily when they are read but not updated.
- SQL or EJB-QL that is needed to implement custom finder methods. This is described in [Brown 2001] and the Application Developer documentation.
To understand how this works, look at the following example. These files were generated with Application Developer by opening the EJB Extensions Editor on an EJB JAR project and then adding a relationship between the Customer and Address EJBs on the Relationships page. This procedure has been covered elsewhere, so I won't repeat it, but instead will show you the Relationships page for this example (see Figure 3 below). (This page defines two relationships: Customer-to-Address and Order-to-LineItem. We will discuss the second relationship below).
Figure 3. Relationships page for Customer-to-Address
When you create this relationship, Application Developer will create or update the extensions file for this EJB Jar file. The extensions file will refer back to elements inside the
ejb-jar.xml
file (the EJB 1.1. DD). It will also add one or more cmp fields to the EJBs as well (More on this later). To understand how the extensions file works, let's first present part of the standard EJB 1.1 DD for our example (some parts have been removed for clarity -- they are described below).
Listing 2.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">
<ejb-jar id="ejb-jar_ID">
<display-name>ProjectForWSDD</display-name>
¦
<enterprise-beans>
<entity id="Customer">
<ejb-name>Customer</ejb-name>
<home>com.ibm.demo.ejbs.CustomerHome</home>
<remote>com.ibm.demo.ejbs.Customer</remote>
<ejb-class>com.ibm.demo.ejbs.CustomerBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-field id="CMPAttribute_6">
<field-name>customerId</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_7">
<field-name>name</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_13">
<field-name>address_addressId</field-name>
</cmp-field>
<primkey-field>customerId</primkey-field>
<ejb-ref id="EjbRef_1">
<ejb-ref-name>ejb/Address</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>com.ibm.demo.ejbs.AddressHome</home>
<remote>com.ibm.demo.ejbs.Address</remote>
<ejb-link>Address</ejb-link>
</ejb-ref>
</entity>
<entity id="Address">
<ejb-name>Address</ejb-name>
<home>com.ibm.demo.ejbs.AddressHome</home>
<remote>com.ibm.demo.ejbs.Address</remote>
<ejb-class>com.ibm.demo.ejbs.AddressBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-field id="CMPAttribute_8">
<field-name>addressId</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_9">
<field-name>street</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_10">
<field-name>city</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_11">
<field-name>state</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_12">
<field-name>zip</field-name>
</cmp-field>
<primkey-field>addressId</primkey-field>
<ejb-ref id="EjbRef_2">
<ejb-ref-name>ejb/Customer</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>com.ibm.demo.ejbs.CustomerHome</home>
<remote>com.ibm.demo.ejbs.Customer</remote>
<ejb-link>Customer</ejb-link>
</ejb-ref>
</entity>
</enterprise-beans>
</ejb-jar>
|
As you may remember from the previous article, the primary thing that Application Developer adds to the EJB DD is the id attributes that uniquely identify each element within the DD. This identification is required not only by the mapping XMI file we examined in the previous article, but also by the extensions document. Having seen EJB DD, you are now ready to examine a simple EJB Extensions file.
Listing 3.
<?xml version="1.0" encoding="UTF-8"?>
<ejbext:EJBJarExtension xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:ejbext="ejbext.xmi"
xmlns:ejb="ejb.xmi" xmlns:ecore="ecore.xmi" xmi:id="ejb-jar_ID_Ext">
<ejbExtensions xmi:type="ejbext:ContainerManagedEntityExtension"
xmi:id="Customer_Ext">
<enterpriseBean xmi:type="ejb:ContainerManagedEntity"
href="META-INF/ejb-jar.xml#Customer"/>
<localRelationshipRoles xmi:id="EjbRelationshipRole_2"
name="address" sourceEjbName="Address" forward="true"
navigable="false" relationship="EjbRelationship_1">
<multiplicity xmi:id="EMultiplicity_1" lower="0" upper="1"/>
<attributes href="META-INF/ejb-jar.xml#CMPAttribute_13"/>
</localRelationshipRoles>
</ejbExtensions>
<ejbExtensions xmi:type="ejbext:ContainerManagedEntityExtension"
xmi:id="Address_Ext">
<enterpriseBean xmi:type="ejb:ContainerManagedEntity"
href="META-INF/ejb-jar.xml#Address"/>
<localRelationshipRoles xmi:id="EjbRelationshipRole_1"
name="customer" sourceEjbName="Customer" forward="false"
navigable="true" relationship="EjbRelationship_1">
<multiplicity xmi:id="EMultiplicity_2" lower="0" upper="1"/>
</localRelationshipRoles>
</ejbExtensions>
<ejbJar href="META-INF/ejb-jar.xml#ejb-jar_ID"/>
<ejbRelationships xmi:id="EjbRelationship_1"
name="Customer-to-Address"
relationshipRoles="EjbRelationshipRole_2 EjbRelationshipRole_1"/>
</ejbext:EJBJarExtension>
|
Let's take a brief look at the structure of this XML file. It is similar but not identical to the EJB 2.0 DD section we examined above. In particular, each EJB has an
<ejbExtensions>
element that corresponds to that EJB. The particular EJB that is extended in the
<ejbExtensions>
object is referred to by an XML reference (an href) to the entity element in the
EJB-JAR.XML
file. For instance, the Customer_Ext
<ejbExtensions>
element refers to the Customer EJB through the following line:
Listing 4.
<enterpriseBean xmi:type="ejb:ContainerManagedEntity" href="META-INF/ejb-jar.xml#Customer"/> |
The
<ejbExtensions>
element also contains (for each individual relationship that the EJB participates in) a localRelationshipsRoles element. This element contains a multiplicity and may contain an attributes element, which acts in nearly the same way as the
<cmr-field>
element in the EJB 2.0 specification, but with one important difference. Since
<cmr-field>
elements are not available in EJB 1.1 (and all container-managed fields must be described as
<cmp-field>
elements), Application Developer must add a new
<cmp-field>
attribute to contain the reference to the related EJBs. In our case, Application Developer added a new attribute named address_address_id to the Customer EJB. That is shown in the
<attributes>
element of the EJB extensions file, which contains a reference to a particular CMP field inside the Address entity element as shown below:
Listing 5.
<attributes href="META-INF/ejb-jar.xml#CMPAttribute_13"/> |
Another difference between the EJB 2.0 specification and the Application Server extensions file is the movement of the definition of a relationship to the bottom of the EJB file. In this case, each relationship is declared as a reference to two roles, each of which is declared inside the
<ejbExtensions>
element for that EJB. As before, Figure 4 below illustrates the relationships between the different parts of the two files.
Figure 4. WebSphere Application Server 4.0 relationship definitions
As you examine this example, you can see that all of the pieces in the EJB 2.0 specification -- relationships, roles, multiplicities, and relationship attributes -- are present in either the Application Server EJB 1.1 DD, or in the Application Server EJB Extensions file.
Now that you've seen how 0..1 to 0..1 relationships are represented in the EJB extensions file and EJB DD, you're ready for more complex relationships. You'll find that they're very similar to the previous example. Consider a standard example from the EJB 2.0 specification -- the relationship between an Order and the Line Items on the Order.
Figure 5. Order and Line Items
In this relationship, since each Order will refer to N LineItems, we can predict a couple of things based on our knowledge of the way EJB relationships were handled in earlier versions of Application Server and the way they are described in the EJB 2.0 specification. We can predict that each Order will refer to a Collection of LineItems (through a
getLineItems()
method). Here is the relationships page in Application Developer to create this relationship, as shown in Figure 6 below.
Figure 6. Order-to-Line Items relationship
Now that you've seen this relationship, you're ready to examine the sections left out of the EJB DD above.
Listing 6.
<entity id="Order">
<ejb-name>Order</ejb-name>
<home>com.ibm.demo.ejbs.OrderHome</home>
<remote>com.ibm.demo.ejbs.Order</remote>
<ejb-class>com.ibm.demo.ejbs.OrderBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-field id="CMPAttribute_1">
<field-name>datePlaced</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_2">
<field-name>orderId</field-name>
</cmp-field>
<primkey-field>orderId</primkey-field>
<ejb-ref id="EjbRef_3">
<ejb-ref-name>ejb/LineItem</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>com.ibm.demo.ejbs.LineItemHome</home>
<remote>com.ibm.demo.ejbs.LineItem</remote>
<ejb-link>LineItem</ejb-link>
</ejb-ref>
</entity>
<entity id="LineItem">
<ejb-name>LineItem</ejb-name>
<home>com.ibm.demo.ejbs.LineItemHome</home>
<remote>com.ibm.demo.ejbs.LineItem</remote>
<ejb-class>com.ibm.demo.ejbs.LineItemBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-field id="CMPAttribute_3">
<field-name>itemId</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_4">
<field-name>price</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_5">
<field-name>description</field-name>
</cmp-field>
<cmp-field id="CMPAttribute_14">
<field-name>order_orderId</field-name>
</cmp-field>
<primkey-field>itemId</primkey-field>
<ejb-ref id="EjbRef_4">
<ejb-ref-name>ejb/Order</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>com.ibm.demo.ejbs.OrderHome</home>
<remote>com.ibm.demo.ejbs.Order</remote>
<ejb-link>Order</ejb-link>
</ejb-ref>
</entity>
|
Here you will notice that there is no new CMP field in the Order, because the Collection of LineItems is not a container-managed field of the order. In other words, the collection itself is not persistent in the database, but is instead generated from the database when the g
etLineItems()
method is received. However, a CMP field has been added to LineItem to represent the connection between the LineItem and its associated order. This reflects the fact that in a relational database, 1 to 0..N relationships are represented by "back-pointers" or foreign keys in the table on the "0..N" side to the table on the "1" side (see [Brown 2000] for a detailed description of this). Likewise, you are now ready to examine the sections left out of the EJB extensions file above that refer to these EJBs.
Listing 7.
<ejbExtensions xmi:type="ejbext:ContainerManagedEntityExtension"
xmi:id="Order_Ext">
<enterpriseBean xmi:type="ejb:ContainerManagedEntity"
href="META-INF/ejb-jar.xml#Order"/>
<localRelationshipRoles xmi:id="EjbRelationshipRole_3"
name="lineItems" sourceEjbName="LineItem" forward="false"
navigable="true" relationship="EjbRelationship_2">
<multiplicity xmi:id="EMultiplicity_3" lower="0" upper="-1"/>
</localRelationshipRoles>
</ejbExtensions>
<ejbExtensions xmi:type="ejbext:ContainerManagedEntityExtension"
xmi:id="LineItem_Ext">
<enterpriseBean xmi:type="ejb:ContainerManagedEntity"
href="META-INF/ejb-jar.xml#LineItem"/>
<localRelationshipRoles xmi:id="EjbRelationshipRole_4"
name="order" sourceEjbName="Order" forward="true"
navigable="true" relationship="EjbRelationship_2">
<multiplicity xmi:id="EMultiplicity_4" lower="1" upper="1"/>
<attributes href="META-INF/ejb-jar.xml#CMPAttribute_14"/>
</localRelationshipRoles>
</ejbExtensions>
<ejbRelationships xmi:id="EjbRelationship_2" name="Order-to-LineItem"
relationshipRoles="EjbRelationshipRole_3 EjbRelationshipRole_4"/>
|
As above, you can see that the extensions file defines a role for each EJB in the relationship, and then defines the relationship as the conjunction of the two roles. Likewise, the LineItem extension defines its connection to the order_order_id attribute defined in the EJB DD. The only odd thing about this section of the EJB extensions file can be found in the multiplicity line for the LineItem EJB:
Listing 8.
<multiplicity xmi:id="EMultiplicity_3" lower="0" upper="-1"/> |
The upper bound of the multiplicity (-1) actually refers to an unbounded multiplicity, or a multiplicity of "N." As you can guess, the legal values for this XML attribute are 0, 1, or -1.
Mapping relationships to database foreign keys
The previous article discussed how Application Server and Application Developer use an XML file called
Schema.dbxmi
to represent a relational database schema that is mapped to an EJB design. In fact, this format changed slightly between the beta and the initial version of Application Developer. You may remember from the previous article that the file had the following format.
Listing 9.
<RDBSchema:RDBDatabase> ...description of the database schema information (derivation, etc.) </RDBSchema:RDBDatabase> <RDBSchema:RDBTable> ...description of the relational database table </RDBSchema:RDBTable> |
Application Developer now splits all Schemas up into a set of files with the following form:
Schema.dbxmi
contains a collection of references to one "schemata" file that contains the
<RDBSchema:RDBDatabase>
element shown above, and N files named
"TableName".tblxmi
contain the
<RDBSchema>
elements described above. For our example, the
Schema.dbxmi
file that is generated in a top-down mapping looks like this.
Listing 10.
<?Xml version="1.0" encoding="UTF-8"?>
<RDBSchema:RDBDatabase xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI"
xmlns:RDBSchema="RDBSchema.xmi" xmi:id="RDBDatabase_1" name="SAMPLE">
<schemata href="ProjectForWSDD/ejbModule/META-INF/Schema/
SAMPLE_NULLID.schxmi#RDBSchema_1"/>
<tableGroup href="ProjectForWSDD/ejbModule/META-INF/Schema/
SAMPLE_NULLID_ORDER.tblxmi#RDBTable_1"/>
<tableGroup href="ProjectForWSDD/ejbModule/META-INF/Schema/
SAMPLE_NULLID_LINEITEM.tblxmi#RDBTable_1"/>
<tableGroup href="ProjectForWSDD/ejbModule/META-INF/Schema/
SAMPLE_NULLID_CUSTOMER.tblxmi#RDBTable_1"/>
<tableGroup href="ProjectForWSDD/ejbModule/META-INF/Schema/
SAMPLE_NULLID_ADDRESS.tblxmi#RDBTable_1"/>
<domain href="DB2UDBNT_V72_Domain.xmi#SQLVendor_1"/>
</RDBSchema:RDBDatabase>
|
As you can see, there is a table file for each of the EJBs in our example. The tables are named the same as the EJBs, as is standard for a top-down mapping. In all other respects, these files are nearly the same as we discussed in the previous article, so we won't describe them again here. Instead, we'll take a look at one of the files (the table XMI file for the Customer Table) to show you the one additional feature that associations add. If you look near the top of this file, you will find the following additional piece of information.
Listing 11.
<columns xmi:id="RDBColumn_3" name="ADDRESS_ADDRESSID"
group="RDBReferenceByKey_1">
<type xmi:type="RDBSchema:SQLCharacterStringType"
xmi:id="SQLCharacterStringType_3" length="250">
<originatingType xmi:type="RDBSchema:SQLCharacterStringType"
href="JavatoDB2UDBNT_V72TypeMaps.xmi#SQLCharacterStringType_250"/>
</type>
</columns>
<namedGroup xmi:type="RDBSchema:SQLReference"
xmi:id="SQLReference_1" name="CUSTOMERPK" members="RDBColumn_1"
table="RDBTable_1" constraint="Constraint_CUSTOMERPK"/>
<namedGroup xmi:type="RDBSchema:RDBReferenceByKey"
xmi:id="RDBReferenceByKey_1" name="ADDRESS" members="RDBColumn_3"
constraint="SQLConstraint_1">
<target href="ProjectForWSDD/ejbModule/META-INF/Schema/
SAMPLE_NULLID_ADDRESS.tblxmi#SQLReference_1"/>
</namedGroup> |
Simplifying things somewhat, a column (Address_AddressId) is defined by reference through the
<namedGroup>
element to be a foreign key to the Address Table. Understanding these foreign-key definitions is key to understanding the mapping of EJB relationships. The previous article described the
map.mapxmi
file that defines how the
<cmp-field>
elements in the EJB DD should be mapped to the fields in the relational database schema. First, examine the following element of the XMI file for our example, and then we'll discuss how it is used to map the EJB relationships to the previously defined foreign key:
Listing 12.
<nested xmi:id="Customer_address---CUSTOMER_ADDRESS">
<helper xmi:type="ejbrdbmapping:ForwardFlattenedFKComposer"
xmi:id="ForwardFlattenedFKComposer_2"/>
<inputs xmi:type="ejbext:EjbRelationshipRole"
href="META-INF/ibm-ejb-jar-ext.xmi#EjbRelationshipRole_2"/>
<inputs xmi:type="ejbext:EjbRelationshipRole"
href="META-INF/ibm-ejb-jar-ext.xmi#EjbRelationshipRole_1"/>
<outputs xmi:type="RDBSchema:RDBReferenceByKey"
href="ProjectForWSDD/ejbModule/META-INF/Schema/
SAMPLE_NULLID_CUSTOMER.tblxmi#RDBReferenceByKey_1"/>
</nested>
|
We're nearing the end of our journey through these files and have come to the crux of the matter. We've seen how the EJB extensions file defines the relationship roles, and how these roles may map to attributes in the EJB DD. We've also seen how foreign keys are represented in the Schema files. This section ties it all together. Here we see that the mapping for Customer's Address field links the two halves of the relationship together with the foreign key reference in the table schema file. The interaction between the three files is shown in Figure 7 below, which illustrates the connection between the EJB extensions file, the Address table schema file, and the map file.
Figure 7. Mapping relationship to foreign key
The only piece you haven't seen is the mapping element that ties together the Order and LineItem. As you can imagine, it is very similar to the previous section tying together the Customer and Address:
Listing 13.
<nested xmi:id="LineItem_order---LINEITEM_ORDER">
<helper xmi:type="ejbrdbmapping:ForwardFlattenedFKComposer"
xmi:id="ForwardFlattenedFKComposer_1"/>
<inputs xmi:type="ejbext:EjbRelationshipRole"
href="META-INF/ibm-ejb-jar-ext.xmi#EjbRelationshipRole_4"/>
<inputs xmi:type="ejbext:EjbRelationshipRole"
href="META-INF/ibm-ejb-jar-ext.xmi#EjbRelationshipRole_3"/>
<outputs xmi:type="RDBSchema:RDBReferenceByKey"
href="ProjectForWSDD/ejbModule/META-INF/Schema/
SAMPLE_NULLID_LINEITEM.tblxmi#RDBReferenceByKey_1"/>
</nested>
|
Again, all that this element does is to link together the two relationship roles that comprise the EJB relationship, and then tie them together with the foreign key that represents that relationship in the database.
Take a deep breath and relax. It's been a long trip, and you've seen a lot of technical detail, but now you should understand the functions and interactions of the XML files used in EJB mapping for Application Developer and Application Server. This should take some of the "magic" out of Application Developer, and help you solve your own mapping problems when using the tools.
Again, thanks to Scott Rich for taking time out of his busy schedule to sit down with me and explain all of this.
- [Brown 2000] Kyle Brown, et. al.,"Enterprise Java Programming with IBM WebSphere," Addison-Wesley, 2000.
- [Brown 2001] Kyle Brown, "Workbook for WebSphere AEs, Version 4.0 for Enterprise JavaBeans, 3rd Edition.
- [Monson-Haefel] Richard Monson-Haefel, "Enterprise JavaBeans, 3rd Edition," O'Reilly, 2001.
- [Sun] Sun Microsystems, EJB 2.0 Final Release Specification , EJB Specifications .
Kyle Brown is a Senior Java Architect with IBM WebSphere Services. He consults with key IBM customers to help them understand how to best apply WebSphere and J2EE technologies to solve their business problems. He has written many articles for industry publications such as The Java Report, and currently writes a column on Enterprise JavaBeans for the VisualAge Developer Domain Technical Journal. He is a co-author of The Design Patterns Smalltalk Companion and Enterprise Java Programming with IBM WebSphere, which will be published by Addison-Wesley in 2000. You can contact him at brownkyl@us.ibm.com.




