An identity relationship establishes an association between business objects or other data on a one-to-one basis. A composite identity relationship relates two business objects through a composite key attribute.
The following sections describe the steps for working with composite identity relationships:
Identity relationship definitions differ from lookup relationship definitions in that the participant types are business objects, not of the type Data (the first selection in the participant types list). As with a simple identity relationship:
However, for a composite identity relationship, the participant attribute for every participant is a composite key. This composite key usually consists of a unique key from a parent business object and a nonunique key from a child business object.
To create a relationship definition for a composite identity relationship, perform the following steps:
Tip: Expand the parent business object and select the key attribute.
Tip: Expand the parent business object, then expand the child attribute within the parent. Select the key attribute from this child object.
Restriction: To manage composite relationships, the server creates internal tables. A table is created for each role in the relationship. A unique index is then created on these tables across all key attributes of the relationship. (In other words, the columns which correspond to the key attributes of the relationship are the participants of the index.) The column sizes of the internal tables have a direct relation to the attributes of the relationship and are determined by the value of the MaxLength attribute for the relationship.
Databases typically have restrictions on the size of the indexes that can be created. For instance, DB2 has an index limitation of 1024 bytes with the default page size. Thus, depending on the MaxLength attribute of a relationship and the number of attributes in a relationship, you could run into an index size restriction while creating composite relationships.
Important:
If the MaxLength attribute for type String is not specified, the default is nvarchar(255) in the SQLServer. Thus, if a relationship has N Keys, all of type String and the default MaxLength attribute of 255 bytes, the index size would be ((N*255)*2) + 16 bytes. You can see that you would exceed the SQLServer 7 limit of 900 bytes quite easily when N takes values of >=2 for the default MaxLength value of 255 bytes for type String.
For more information on how to create a relationship definition for a composite identity relationship, see "Defining identity relationships".
Table 100 shows the activity function blocks that the Mapping API
provides to maintain a composite identity relationship from the child
attribute of the parent source business object. The actions that these
methods take depends on the source object's verb and the calling
context.
Table 100. Maintaining a composite identity relationship from the child attribute
Function block | Description |
---|---|
General/APIs/Identity Relationship/
Maintain Child Verb | Set source child verb correctly |
General/APIs/Identity Relationship/
Maintain Composite Relationship | Perform appropriate action on the relationship tables |
The Maintain Composite Relationship function block will generate Java code that calls the mapping API maintainCompositeRelationship(), which will manage relationship tables for a composite identity relationship. This method ensures that the relationship instances contain the associated application-specific key values for each relationship instance ID. This method automatically handles all of the basic adding and deleting of participants and relationship instances for a composite identity relationship.
The actions that maintainCompositeRelationship() takes are based on the value of the business object's verb and the calling context. The method iterates through the child objects of a specified participant, calling the maintainSimpleIdentityRelationship() on each one to correctly set the child key value. As with maintainSimpleIdentityRelationship(), the action that maintainCompositeRelationship() takes is based on the following information:
For information on the actions that maintainSimpleIdentityRelationship() takes, see "Accessing identity relationship tables".
The maintainCompositeRelationship() method deals only with composite keys that extend to only two nested levels. In other words, the method cannot handle the case where the child object's composite key depends on values in its grandparent objects.
Example: If A is the top-level business object, B is the child of A, and C is the child of B, the two methods will not support the participant definitions for the child object C that are as follows:
key attribute of A: ID key attribute of B: B[0].ID key attribute of C: B[0].C[0].ID
key attribute of A: ID key attribute of C: B[0].C[0].ID
To access a grandchild object, these methods only support the participant definitions that are as follows:
key attribute of B: ID key attribute of C: C[0].ID
key attribute of B: ID first key attribute of C: C[0].ID1 second key attribute of C: C[0].ID2
The Maintain Child Verb function block will generate Java code that calls the mapping API maintainChildVerb(), which will maintain the verb of the child objects in the destination business object. It can handle child objects whose key attributes are part of a composite identity relationship. When you call maintainChildVerb() as part of a composite relationship, make sure that its last parameter has a value of true. This method ensures that the verb settings are appropriate given the verb in the parent source object and the calling context. For more information on the actions of maintainChildVerb(), see "Setting the source child verb".
Once you have created the relationship definition and participant
definitions for the composite identity relationship, you can customize the map
to maintain the composite identity relationship. A composite identity
relationship manages a composite key. Therefore, managing this kind of
relationship involves managing both parts of the composite key. To code
a composite identity relationship, you need to customize the mapping
transformation rules for both the parent and child business objects, as Table 101 shows.
Table 101. Activity function blocks for a composite identity relationship
Map involved | Business object involved | Attribute | Activity function blocks |
---|---|---|---|
Main | Parent business object | Top-level business object | Use a Cross-Reference transformation rule |
|
| Child attribute (child business object) | General/APIs/Identity Relationship/Maintain Composite
Relationship General/APIs/Identity Relationship/Maintain Child Verb General/APIs/Identity Relationship/Update My Children (optional) |
Submap | Child business
object | Key attribute (nonunique key) | Define a Move or Set Value transformation for the verb. |
If child business objects have a nonunique key attribute, you can relate these child business objects in a composite identity relationship.
The following sections describe the steps for customizing this composite identity relationship:
In the map for the parent business object (the main map), add the mapping code to the parent attributes:
The child attribute of the parent object contains the child business object. This child object is usually a multiple cardinality business object. It contains a key attribute whose value identifies the child. However, this key value is not required to be unique. Therefore, it does not uniquely identify one child object among those for the same parent nor is it sufficient to identify the child object among child objects for all instances of the parent object.
To identify such a child object uniquely, the relationship uses a composite key. In the composite key, the parent key uniquely identifies the parent object. The combination of parent key and child key uniquely identifies the child object. In the map for the parent business object (the main map), add the mapping code to the attribute that contains the child business object. In Activity Editor for this attribute, perform the following steps to code a composite identity relationship:
The last input parameter of the General/APIs/Identity Relationship/Maintain Child Verb function block is a boolean flag to indicate whether the child objects are participating in a composite relationship. Make sure you pass a value of true as the last argument to maintainChildVerb() because this child object participates in a composite, not a simple identity relationship. Make sure you call maintainChildVerb() before the code that calls the submap. For more information, see "Setting the source child verb".
Tip: Make sure the transformation rule that contains the Update My Children function block has an execution order after the transformation rule that contains the Maintain Composite Relationship function block.
The following example describes how the map can be customized for a Composite Identity Relationship.
The goal of this custom activity is to use the maintainChildVerb() API to set
the child business object verb based on the map execution context and the verb
of the parent business object. Figure 132 shows this custom activity.
The goal of this custom activity is to use the maintainComposite
Relationship() API to maintain a composite identity relationship within the
map. Figure 133 shows this custom activity.
Figure 133. Using the Maintain Composite Relationship function block
The goal of this custom activity is to use the updateMyChildren() API to
add or delete child instances in the specified parent/child relationship of
the identity relationship. Figure 134 shows this custom activity.
Here is a sample of how the code in the child attribute of the parent map might look. This code fragment would exist in the Order Line Item attribute of an SAP Order business object. It uses maintainChildVerb() to set the child object verbs, then calls a submap (Sub_SaOrderLieItem_to_CwOrderLineItem) in a for loop to handle mapping of the Order line items child object:
{ BusObjArray srcCollection_For_ObjSAP_Order_SAP_OrderLineItem = ObjSAP_Order.getBusObjArray("SAP_OrderLineItem"); // // LOOP ONLY ON NON-EMPTY ARRAYS // ----------------------------- // // Perform the loop only if the source array is non-empty. // if ((srcCollection_For_ObjSAP_Order_SAP_OrderLineItem != null) && (srcCollection_For_ObjSAP_Order_SAP_OrderLineItem.size() > 0)) { int currentBusObjIndex_For_ObjSAP_Order_SAP_OrderLineItem; int lastInputIndex_For_ObjSAP_Order_SAP_OrderLineItem = srcCollection_For_ObjSAP_Order_SAP_OrderLineItem.getLastIndex(); // ---- IdentityRelationship.maintainChildVerb( "OrdrLine", "SAPOrln", "CWOrln", ObjSAP_Order, "SAP_OrderLineItem", ObjOrder, "OrderLineItem", cwExecCtx, true, true); // ---- for (currentBusObjIndex_For_ObjSAP_Order_SAP_ OrderLineItem = 0; currentBusObjIndex_For_ObjSAP_Order_SAP_OrderLineItem <= lastInputIndex_For_ObjSAP_Order_SAP_OrderLineItem; currentBusObjIndex_For_ObjSAP_Order_SAP_OrderLineItem++) { BusObj currentBusObj_For_ObjSAP_Order_SAP_OrderLineItem = (BusObj) (srcCollection_For_ObjSAP_Order_SAP_OrderLineItem.elementAt( currentBusObjIndex_For_ObjSAP_Order_SAP_OrderLineItem)); // // INVOKE MAP ON VALID OBJECTS // --------------------------- // // Invoke the map only on those children objects that meet // certain criteria. // if (currentBusObj_For_ObjSAP_Order_SAP_OrderLineItem != null) { BusObj[] _cw_inObjs = new BusObj[2]; _cw_inObjs[0] = currentBusObj_For_ObjSAP_Order_SAP_OrderLineItem; _cw_inObjs[1] = ObjSAP_Order; logInfo ("*** Inside SAPCW header, verb is: " + (_cw_inObjs[0].getVerb())); try { BusObj[] _cw_outObjs = DtpMapService.runMap( "Sub_SaOrderLineItem_to_CwOrderLineItem", "CwMap", _cw_inObjs, cwExecCtx); _cw_outObjs[0].setVerb(_cw_inObjs[0].getVerb()); ObjOrder.setWithCreate("OrderLineItem", _cw_outObjs[0]); } catch (MapNotFoundException me) { logError(5502, " Sub_SaOrderLineItem_to_CwOrderLineItem "); throw new MapFailureException ("Submap not found"); } } } // Start of the child relationship code BusObjArray temp = (BusObjArray)ObjOrder.get("OrderLineItem"); try { IdentityRelationship.maintainCompositeRelationship( "OrdrLine", "SAPOrln", ObjSAP_Order, temp, cwExecCtx); } catch RelationshipRuntimeException re { logError(re.toString()); } // This call to updateMyChildren() assumes the existence of the // OrdrOrln parent/child relationship between the SAP_Order // (parent) and SAP_OrderItem (child) IdentityRelationship.updateMyChildren( "OrdrOrln", "SAOrders", ObjSAP_Order, "SAOrdrLn", "LineItem", "OrdrLine", "SAPOrln", cwExecCtx); // End of the child relationship code } }
In the map for the child business object (the submap), add the mapping code to the the key attribute of the child object. The only code you need to add is a call to the setVerb() method to set the child object's verb to the parent object's verb. For more information, see "Setting the destination business object verb".
// maintainCompositeRelationship() is called in the parent map.