Introducing entity subtypes in IBM InfoSphere Master Information Hub

Write entity subtypes and supporting services

In this tutorial, learn how to implement entity subtypes and supporting services for IBM® InfoSphere™ Master Data Management Server and InfoSphere Master Information Hub. Using an entity subtyping framework allows you to introduce new entities that may be processed by the services of their parent entities, which helps achieve service interoperability and extensibility for a new domain created using Master Information Hub.

Share:

Stephanie J. Hazlewood (stephanie@ca.ibm.com), Software Architect, IBM

Stephanie Hazlewood is an architect on the IBM Master Data Management Server team at the Toronto Lab and leads the Advanced Technology (AdTech) team for MDM. She has contributed to the core design and development of the MDM Server product since its first release over eight years ago. Along with Master Data Management architecture and solutions, her expertise includes Knowledge Management (KM) software and practices, and virtual communities of learning. Stephanie worked previously for DWL and the University of Toronto's Center for Applied Cognitive Science (now known as Institute for Knowledge Innovation and Technology), and holds a Masters degree from the University of Western Ontario.



Lin Qiao (linqiao@ca.ibm.com), Sofrware Architect, IBM

Lin Qiao photoLin Qiao is an architect on the InfoSphere Master Data Management Server team at the Toronto Lab and has been with the product team for over seven years. She has designed and lead the development of a number of key MDM Server features and worked previously for DWL.



28 January 2010

Also available in Chinese

Before you start

When you are defining new entities for a solution using InfoSphere Master Information Hub or InfoSphere Master Data Management Server, you may have a requirement that demand services be able to process entities having a supertype-subtype relationship. Entities are distinct if they have no attributes in common. Entities that share some attributes, including an identifier (primary key), but not others may be modelled as having a common supertype. Although these entities may share attributes, they are not the same. For example, humans and plants share attributes that serve to define them as living things (generalization), but the attributes that they do not share further specialize this definition in ways that would require the different treatment of each. In the case of an MDM or Master Information Hub solution, the business may require entities participating in the special supertype-subtype relationship participate in a common set of services, but result in being processed by those services in different ways. This tutorial shows you how to implement new type hierarchies and define associated services that allow for this specialized processing.

Objectives

  • Understand when to use subtypes and when to use data extensions.
  • Understand how to create an entity supertype, subtypes, and associated services to allow the processing of each.
  • Gain insight into the structure of Master Information Hub entities and services, and the possibilities you have to customize the implementation of a subtyped entity and its services.
  • Step through the creation of subtyped entities and three service types that may consume them (add, update, and inquiry by identifier) with performance considerations in mind.
  • Step through the creation of an extension subtype for a pre-existing type hierarchy and corresponding services developed as part of a Master Information Hub solution.

Prerequisites

This tutorial is written for IT architects and IT specialists with an interest in learning more about how to design and develop services for InfoSphere Master Information Hub. This tutorial assumes that you have experience developing solutions using the InfoSphere Master Information Hub/MDM Server Workbench. More specifically, it assumes:

  • You can use and configure a development environment using the Development Environment Setup Tool (DEST)
  • You are familiar with creating, customizing, and deploying addition and extensions to entities using the InfoSphere Master Information Hub/MDM Server Workbench

System requirements

To complete this tutorial, your system should meet the following requirements:

  • 2GB memory or more
  • 15GB free disk space
  • A system having a Windows operating system on which the IBM Rational® Software Architect, Version 7.5.4 for IBM WebSphere® Software (or newer) can be installed with the Master Information Hub Workbench

This tutorial has been developed for use with Version 9.0 of InfoSphere Master Information Hub and InfoSphere Master Data Management Server.


Overview

Many established organizations end up having unmanaged master data, whether it be the result of mergers and acquisitions or information repositories siloed by line of business information that should be shared but is not. Unmanaged master data leads to data inconsistency and inaccuracy. IBM InfoSphere Master Information Hub may be used to create a services-based Java™ EE application that provides a consolidated view and distribution point for information that should be shared by these operational systems.

Whereas InfoSphere Master Data Server provides out-of-the-box operational capabilities for the Party, Product, and Account domains, Master Information Hub provides the building blocks, a runtime platform, and set of tools that enable the creation of custom domains to deal with more of the non-traditional master data use cases (reference data, for example). In the operational style of master data management, the applications built with Master Information Hub act as an online-transaction processing (OLTP) system responding to requests from multiple service consumers. These stateless services, whether those delivered out-of-the-box with the platform or created using the Master Information Hub Workbench, leverage a robust application framework that provides key features such as auditing, validation, and rules of visibility as part of a Services-Oriented Architecture (SOA).

Figure 1. InfoSphere Master Information Hub and MDM Server (domains)
A figure containing an image of the InfoSphere Master Information Hub repository, runtime platform, and domains (MDM Server domains and the custom domains that may be built on the Master Information Hub platform. The figure depicts the Master Information Hub Workbench's ability to generate services and structures to customize existing domains as well as create new ones.

The tooling, the InfoSphere Master Information Hub Workbench, may be used to facilitate the creation and extension of entities, services, and user interfaces to aid with the stewardship of the information being managed. It provides the modeling, code generation, development, and testing environment required to develop for InfoSphere Master Information Hub. The Master Information Hub Workbench is integrated with IBM Rational Software Architect, thereby leveraging access to the standard software development capabilities this product provides, including integration with source code control and Java EE deployment and testing environments with WebSphere Application Server.

The building blocks for a custom domain are what are termed additions. These are the interfaces, entities, services, and supporting metadata/database structures required to process information on the Master Information Hub platform. The Master Information Hub Workbench provides functionality to create new additions, and it is upon these assets that this tutorial provides a guideline to build and leverage the entity subtyping framework for a new domain.


The entity subtyping feature

Version 9.0 of Master Information Hub and MDM Server introduce the entity subtyping feature.

As added functionality to the runtime platform, the feature allows for:

  • Multiple levels of entity subtyping and no limit on number of children a type may have. (Note: This tutorial recommends a 1:1 database table to subtype mapping, and as such, performance will be impacted as the depth of the hierarchy increases. Model subtype hierarchies with this in mind.)
  • Object polymorphism—the ability to define unique business keys, validations, and rules of visibility (RoV).
  • The ability of parent service to process subtype(s) with the expected service behavior to be identical to that resulting from the execution of the granular service of that type.
  • The ability to extend subtypes using extension framework (behavior extensions, data extensions). (Note: Data extensions and subtype extensions are limited to leaf-nodes; see "Male" in Figure 2).
  • The ability to define persistence and query strategies for each type and any child objects contained by the type, its parent type, or both.

The entity subtyping feature does not allow for:

  • Subtypes to have more than one supertype (no multiple inheritance)
  • Subtypes to be created for existing entities in MDM Server or the Master Information Hub

The runtime platform for Master Information Hub and MDM Server uses metadata to discover and redirect service calls to an appropriate subtype service if there is one. For example, consider the type hierarchy in Figure 2 and its accompanying services. Expect that if a call to addParty(Pet) is made, the behavior of the service would be as if addPet(Pet) was the call originally made.

Figure 2. Subtype hierarchy and service behavior
Depiction of hierarchy of types: Party (SParty) as the root parent type; LivingThing as a subtypes of Party; Human and Pet as subtypes of LivingThing; and Male a further subtype of Human. Male is identified in another color to indicate that this could be an extension subtype to a prewritten type hierarchy.

Table 1 provides a list of example services, indicating that for every subtype passed to a supertype method, the service behavior would be to execute as if the service call were originally made to the subtype's service.

Table 1. Example services
Calling parent serviceBehaves as if the following service call was made
addSParty(LivingThing)addLivingThing(LivingThing)
updateSParty(Human)updateHuman(Human)
getHuman(MaleID, DWLControl)getMale(MaleID, DWLControl)
addSParty(Male)addMale(Male)

Note: The entities described in this tutorial are not existing MDM entities. The use of a Party entity is for demonstrative purposes only and does not represent the Party entity or its services in InfoSphere Master Data Management Server, Version 9.0. Subtyping of existing domain entities using the patterns described in this tutorial is not supported.

Using the example built in this tutorial, Figure 3 depicts a call to the addParty service on the controller, where a PetBObj is passed, resulting in the service flow being intercepted in the executeTx() method. The handleSubtypes method uses metadata to derive and redirect the service call to the appropriate method to process this type (in this case, handleAddPet). Because the redirection takes place prior to the call to preExecute(), all controller-level preExecute functionality will be carried out for the appropriate subtype being passed to the system.

Figure 3. Parent service executed for passing a subtype
Depiction of a sequence diagram showing the redirection of method calls to process a subtyped entity.

When to use an entity subtype, rather than a data extension

Although Java inheritance is the underpinning mechanism used for both subtypes and data extensions, there is a key difference in the way in which the Master Information Hub platform interprets each. Extending and adding additional fields to an existing Master Information Hub entity does not require the introduction of new services to provide processing (validation and business logic, for example) unique to the new entity. These data extensions are subject to processing by all predefined services for the entity using calls made to the extension framework (for example, addRecord, updateRecord, getRecord, deleteRecord API calls). For an entity subtype, the addition of new fields provides new business meaning for an entity. That is, new services are required, and the processing of the entity is independent of the processing of its parent type. For example, entity supertypes have their own unique business logic, validations, business keys, rules of visibility, and audit history. It should be noted that as of Version 9.0, the pre-existing entities in the data model may not be modified to leverage the entity subtyping framework.

Table 2. Comparison of entity subtype and data extension
SubtypeData extension
Not characterized as an extensionAlways characterized as an extension in request/response (TCRMExtension/DWLExtension)
Requires new granular services for processing different behavior or business logic unique for that typeDoes not require new additional services for processing, and therefore only participates/gets pulled into existing out-of-the-box services
Defines new business keys; defines uniqueness of the business objectShould use the same business key configuration as the object being extended

Create an application in InfoSphere Master Information Hub that leverages entity subtyping

Create the sample application

In this section, you are going to create a set of MDM entities that make up a type hierarchy and create the associated services for each of the entities. You may use the InfoSphere Master Information Hub or Master Data Management Server, Version 9 Workbench to create these entities and generate the resources required to deploy them. After doing this, follow the steps to customize the generated resources to enable the services to leverage the entity subtyping framework. Figure 4 depicts the entities and their relationships in the type hierarchy for this tutorial.

Create the sample application and generate the resources in the following steps. Please refer to the InfoSphere Master Information Hub Workbench Guide for the more information on how to use the workbench if you are not familiar with this tool.

  1. In Master Information Hub Workbench, create an MDM Module Project.
  2. In the new module project, create an MDM entity for each entity in the sample type hierarchy.

    To define the entities:

    • Ensure you define the same primary key for the tables of the entities. In this example, each entity has partyId as its primary key.
    • A groupName field with type "String" must be defined in the root type entity. It is a mandatory field that gets used by the entity subtyping framework to derive the true type of a record for inquiry transactions when only an identifier (for example, partyId) is provided to the service. It is mandatory to define this only in the root type of a hierarchy.

    Figure 4 and Table 3 provide information for each of the sample entities:

    Figure 4. The data model
    Depiction of the entity-relationship diagram or data model for the entities to be created for this tutorial.
Table 3. The sample Master Information Hub entities and their attributes
Master Information Hub entityMaster Information Hub entity attributes
SPartypartyId: Long
displayName: String
groupName: String
LivingThingpartyId: Long
age: Short
HumanpartyId: Long
citizenship: String
PetpartyId: Long
kidIndicator: String
  1. When all entities are defined, use the Workbench to generate source code and resources.

Customize the source code

The code and resources generated as-is by the Master Information Hub Workbench (Version 9.0) do not automatically leverage the platform's entity subtyping framework. You must customize some of these assets to enable the subtype support.

  1. Implement the relationships between business objects (BObjs), as shown in Figure 5:
    Figure 5. Business object (BObj) class diagram
    Depiction of relationships between business objects, where LivingThingBObj extends SPartyBObj; HumanBObj extends LivingThingBOBj; and PetBObj extends LivingThingBObj.

    LivingThingBObj extends SPartyBObj; HumanBObj extends LivingThingBOBj; and PetBObj extends LivingThingBObj.

  2. Next, customize the generated code for each BObj in the sample hierarchy.
    1. For the root type BObj, remove the generated code that puts the groupName into the metaDataMap. For example, in init() of SPartyBObj, remove the following generated line:
           metaDataMap.put("GroupName", null);
    2. Also, remove the following generated line from refreshMap() of SPartyBObj:
           metaDataMap.put("GroupName", getGroupName());
    3. For every subtype BObj, remove the getter/setter code for the LastUpdateTxId and LastUpdateUser attributes, as they are already present in the root entity type. For example, in LivingThingBObj:
      • Remove the getter and setter methods for LivingThingLastUpdateTxId.
      • Remove the getter and setter methods for LivingThingLastUpdateUser.
      • As you did with GroupName in the root entity, remove LivingThingLastUpdateTxId and LivingThingLastUpdateUser from the metaDataMap.
  3. Customize the component classes and their relationships. Use one business component per entity type in the hierarchy. Figure 6 depicts the business components and the relationships you need to implement for this tutorial. For example, the LivingThingComponent extends SPartyComponent.
    Figure 6. Component class diagram
    This figure depicts the controller components, business components, and the interfaces each implement for this tutorial. The SPartyTxnBean class is the transaction controller component that implements the SPartyTxn interface. All of the add and update transactions for the types in the hierarchy (SParty, LivingThing, Human, and Pet) reside on this interface. The SPartyFinderImpl class is the finder controller component that implements the SPartyFinder interface. All of the inquiry services for the types in the hierarchy reside on this interface. The SPartyComponent is a business component that implements the SParty interface and extends from the TCRMComponent. The LivingThingComponent implements the LivingThing interface and extends from the SPartyComponent. Both the HumanComponent and PetComponent are business components that extend from the LivingThingComponent, but implement the Human and Pet interfaces respectively. There is no inheritance relationship between the interfaces of the business components. For example, the LivingThing interface does not extend from the SParty interface and so on. The add, update, and get services for the SParty type all reside on the SParty interface. The add, update, and get services for the LivingThing type all reside on the LivingThing interface, and so on.
  4. Leverage the entity subtyping framework for the add transaction for each entity by customizing its handleAdd() method in its business component.
    • For a root entity, the groupName must be populated before the object itself is persisted. For example, in Listing 1, the code in bold shows the handleAddSParty() in SPartyComponent:
      Listing 1. handleAddSParty() in SPartyComponent
      public DWLResponse handleAddSParty(SPartyBObj theSPartyBObj) throws Exception {
          ......  //prepare status 
      
          // Populate group_name for the root type from metadata v_group table.
          EObjSParty eobjSParty = theSPartyBObj.getEObjSParty();
          IGroupElementService theGroupElementService = GroupElementServiceHelper
                                   .getGroupElementService();
          Group group = theGroupElementService.getGroup(theSPartyBObj.getClass()
                          .getName());
          eobjSParty.setGroupName(group.getGroupName());	
          		
          // Pluggable Key Structure implementation
          ......
          
          Persistence theSPartyBObjPersistence = getBObjPersistenceFactory()
      			.createSPartyBObjPersistence(SPartyBObjQuery.SPARTY_ADD,
      					theSPartyBObj);
          theSPartyBObjPersistence.persistAdd();
      
          ....  //persist child objects if there is any             
          ...... //prepare and return the response 
      }
    • For a subtype entity, its supertype entity needs to be persisted first, and then its primary key is populated from its super type. For example, the sample code in Listing 2 shows the handleAddLivingThing() in LivingThingComponent:
      Listing 2. handleAddLivingThing() in LivingThingComponent
      public DWLResponse handleAddLivingThing(LivingThingBObj theLivingThingBObj)
                            throws Exception {
          // 1. persist super type data
          DWLResponse response = handleAddSParty(theLivingThingBObj);
      
          // 2. populate the primary key from super type to sub type EObj
          theLivingThingBObj.getEObjLivingThing().setSPartyId(
      		theLivingThingBObj.getEObjSParty().getSPartyId());
      
          // 3. persist subtype data 
          Persistence theLivingThingBObjPersistence = getBObjPersistenceFactory()
      				.createLivingThingBObjPersistence(
      				LivingThingBObjQuery.LIVING_THING_ADD,
      				theLivingThingBObj);
          theLivingThingBObjPersistence.persistAdd();
      
          return response;
      }
  5. Leverage the entity subtyping framework in the update transaction for each subtype entity by customizing the handleUpdate() method in its component.

    The update transaction for the root entity is the same as for a regular entity and requires no change. For a subtype, its supertype needs to be updated first. For example, Listing 3 shows the handleUpdateLivingThing() in LivingThingComponent:
    Listing 3. handleUpdateLivingThing() in LivingThingComponent
    public DWLResponse handleUpdateLivingThing(
    	LivingThingBObj theLivingThingBObj) throws Exception {
    
        //1. Update super type
        DWLResponse response = handleUpdateSParty(theLivingThingBObj);
    
        //2. Update sub type
        if (!theLivingThingBObj.isRedundantUpdate()) {
          Persistence theLivingThingBObjPersistence = getBObjPersistenceFactory()
                .createLivingThingBObjPersistence(
          LivingThingBObjQuery.LIVING_THING_UPDATE,
    		theLivingThingBObj);
          theLivingThingBObjPersistence.persistUpdate();
        }
    
        return response;
    }
  6. Leverage the entity subtyping framework for the get transaction (by identifier) for each entity by customizing the handleGet() method in its component.

    The get transaction in the subtype entity does not call its supertype implementation, thereby making only a single query to the database. That is, one SQL containing all the relevant joins should be used to fetch data from multiple tables.
    1. In the query for the root get transaction, make sure GROUPNAME is returned. For example, Listing 4 provides the query SQL for getSParty as defined in SPartyInquiryData:
      Listing 4. SQL for getSParty in SPartyInquiryData
      static final String getSPartySql = "SELECT r.SPARTY_ID SPARTY_ID, 
      r.DISPLAY_NAME DISPLAY_NAME, r.GROUP_NAME GROUPNAME,r.LAST_UPDATE_DT 
      LAST_UPDATE_DT, r.LAST_UPDATE_USER LAST_UPDATE_USER,r.LAST_UPDATE_TX_ID 
      LAST_UPDATE_TX_ID FROM SPARTY r WHERE r.SPARTY_ID = ? ";
    2. Modify the query for each subtype entity to use JOIN to retrieve the data distributed in multiple tables. For example, the data for a Pet entity is distributed in table SParty, LivingThing, and Pet. Update the query SQL for getPet in PetInquiryData to retrieve the data by one SQL:
      Listing 5. SQL for getPet in PetInquiryData
      Public interface MaleInquiryData{
      
          ......
      
          static final String tableAliasString = "tableAlias (
            PET => mdm.est.samples.entityObject.EObjPet,
            H_PET => mdm.est.samples.entityObject.EObjPet,
            LIVINGTHING => mdm.est.samples.entityObject.EObjLivingThing,
            H_LIVINGTHING => mdm.est.samples.entityObject.EObjLivingThing,
            SPARTY => mdm.est.samples.entityObject.EObjSParty,
            H_SPARTY => mdm.est.samples.entityObject.EObjSParty)";
      
          @Select(sql="SELECT C.SPARTY_ID, C.KID_INDICATOR, C.LAST_UPDATE_DT, 
          C.LAST_UPDATE_USER, C.LAST_UPDATE_TX_ID, B.SPARTY_ID, B.LAST_UPDATE_DT, 
          B.LAST_UPDATE_USER, B.LAST_UPDATE_TX_ID, A.SPARTY_ID, A.DISPLAY_NAME, 
          A.LAST_UPDATE_DT, A.LAST_UPDATE_USER, A.LAST_UPDATE_TX_ID FROM SPARTY A,
          LIVINGTHING B, PET C  WHERE A.SPARTY_ID = B.SPARTY_ID AND B.SPARTY_ID = 
          C.SPARTY_ID AND C.SPARTY_ID = ? ", pattern=tableAliasString)
          Iterator<ResultQueue3<EObjPet,EObjLivingThing,EObjSParty>> 
               getPet(Object[] parameters);  
      }
    3. Customize the createObject() method in the ResultSetProcessor of each subtype.
      Listing 6. PetResultSetProcessor
      public Object createObject(Object eObjs) throws Exception {
          PetBObj theBObj = (PetBObj) super.createBObj(PetBObj.class);
          Queue eobjQueue = (Queue) eObjs;
      
          if( !eobjQueue.isEmpty() ) {
              EObjPet theEObj = (EObjPet)  eobjQueue.remove();
              theBObj.setEObjPet( theEObj );
                  
              EObjLivingThing livingthingEObj = (EObjLivingThing) eobjQueue.remove();
              theBObj.setEObjLivingThing(livingthingEObj);
                  
              EObjSParty spartyEObj = (EObjSParty) eobjQueue.remove();
              theBObj.setEObjSParty(spartyEObj);
          }
          return theBObj;
      }
  7. Customize Web services for each entity.
    • Implement the relationships for the transfer object classes. For example, make LivingThing class extend SParty. The relationships are depicted in Figure 7:
      Figure 7. Web services transfer object class diagram
      This diagram depicts the relationships that must be established between the transfer objects that were generated for the entities. The Human and Pet transfer object classes must both extend the LivingThing transfer object class. LivingThing must extend the SParty transfer object class, and the SParty transfer object must extend the PersistableObject class.
    • Remove the getter and setter for SPartyId in the subtype transfer object classes. They are LivingThing, Human, and Pet in this sample.
    • Implement the relationships for the response classes. For example, make LivingThingReponse class extend SPartyResponse. The relationships for this sample are depicted in Figure 8:
      Figure 8. Web services response object class diagram
      This diagram depicts the relationships that must be established between the response objects that were generated for the entities. The HumanResponse and PetResponse classes must both extend the LivingThingResponse class. LivingThingResponse must extend the SPartyResponse class, and the SPartyResponse class must extend the ResponseObject class.
    • Implement the relationships for the converter classes. For example, make LivingThingBObjConverter class extend the SPartyBObjConverter. The relationships for this sample are depicted in Figure 9:
      Figure 9. Web services converter class diagram
      This diagram depicts the relationships that must be established between the converter objects that were generated for the entities. The HumanBObjConverter and PetBObjConverter classes must both extend the LivingThingBObjConverter class. LivingThingBObjConverter must extend the SPartyBObjConverter class, and the SPartyBObjConverter class must extend the SimpleBObjConverter class.

Customize the XSD

  1. In the request and response XML Schema Definition (XSD) for Remote Method Invocation (RMI) service, define extension relationships between BObj, as shown in Figure 5 above, and note the following:
    • In the root entity type definition, move the common object declaration, like TCRMExtension and PrimaryKeyBObj, to the beginning of the type.
    • In the root entity type definition, make sure GroupName is removed.
    • In the subtype entity definition, make sure LastUdpateUser and LastUpdateTxId are removed.

    Listing 7 shows the XSD for SPartyBObj and LivingThingBObj:

    Listing 7. XSD for SPartyBObj and LivingThingBObj
    <xsd:element name="SPartyBObj" substitutionGroup="CommonBObj" 
         type="SPartyBObjType" />
    <xsd:complexType name="SPartyBObjType">
      <xsd:complexContent>
      <xsd:extension base="CommonBObjType">
      <xsd:sequence>
        <xsd:element ref="TCRMExtension" minOccurs="0" maxOccurs="1" />
        <xsd:element ref="PrimaryKeyBObj" minOccurs="0" maxOccurs="1" />
        <xsd:element ref="ComponentID" minOccurs="0" maxOccurs="1" />
        <xsd:element ref="ObjectReferenceId" minOccurs="0" maxOccurs="1" />
        <xsd:element ref="SPartyId" minOccurs="0" maxOccurs="1" />
        <xsd:element ref="DisplayName" minOccurs="0" maxOccurs="1" />
        <xsd:element ref="SPartyLastUpdateDate" minOccurs="0" maxOccurs="1" />
        <xsd:element ref="SPartyLastUpdateUser" minOccurs="0" maxOccurs="1" />
        <xsd:element ref="SPartyLastUpdateTxId" minOccurs="0" maxOccurs="1" />
        <xsd:element ref="IdentifierBObj" minOccurs="0" maxOccurs="unbounded" />
        </xsd:sequence>
        </xsd:extension>
        </xsd:complexContent>
     </xsd:complexType>
    
    <xsd:element name="LivingThingBObj" substitutionGroup="CommonBObj" 
        type="LivingThingBObjType" />
    <xsd:complexType name="LivingThingBObjType">
      <xsd:complexContent>
      <xsd:extension base="SPartyBObjType"> 
      <xsd:sequence>
        <xsd:element ref="Age" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="LivingThingLastUpdateDate" minOccurs="0" maxOccurs="1"/>
      </xsd:sequence>
    </xsd:extension>
    </xsd:complexContent>
    </xsd:complexType>
  2. For the WebService XSD, define the extension relationship for entities, as shown in Figure 5 above. For example, Human extends from LivingThing.

Customize the metadata

Configuring the business object and service metadata for the entity hierarchy is the key to enabling the subtype framework. With this, services can be redirected properly by the entity subtyping framework. Customize the generated metadata using the following steps:

  1. In V_element table, set up the group relationship by PARENT_GRP_NAME column. For example:
    Listing 8. Generated SQL for populating metadata : V_ELEMENT table
    INSERT INTO V_GROUP (GROUP_NAME, APPLICATION, OBJECT_NAME, LAST_UPDATE_DT, SORTBY) 
      VALUES ('SPartyBObj', 'TCRM', 'mdm.est.samples.component.SPartyBObj', 
        CURRENT TIMESTAMP, 'LAST_UPDATE_DT');
    
    INSERT INTO V_GROUP (GROUP_NAME, APPLICATION, OBJECT_NAME, LAST_UPDATE_DT, SORTBY,
       PARENT_GRP_NAME) 
      VALUES ('LivingThingBObj', 'TCRM', 'mdm.est.samples.component.LivingThingBObj', 
        CURRENT TIMESTAMP, 'LAST_UPDATE_DT', 'SPartyBObj');
    
    INSERT INTO V_GROUP (GROUP_NAME, APPLICATION, OBJECT_NAME, LAST_UPDATE_DT, SORTBY, 
        PARENT_GRP_NAME) 
      VALUES ('HumanBObj', 'TCRM', 'mdm.est.samples.component.HumanBObj', 
        CURRENT TIMESTAMP, 'LAST_UPDATE_DT', 'LivingThingBObj');
  2. In CDBUSINESSTXTP table, set up the transaction relationship by PARENT_BUSINESS_TX_TP_CD column. For example:
    Listing 9. Generated SQL for populating metadata: CDBUSINESTXTP table
    INSERT INTO CDBUSINESSTXTP (BUSINESS_TX_TP_CD, NAME, DESCRIPTION, EXPIRY_DT, 
        LAST_UPDATE_DT, TX_LOG_IND, TX_OBJECT_TP, DEPRECATED_SINCE, DWL_PROD_TP_CD) 
      VALUES (1000013, 'addSParty',  null, null, CURRENT TIMESTAMP, 'Y', 'P', null, 1);
    
    INSERT INTO CDBUSINESSTXTP (BUSINESS_TX_TP_CD, NAME, DESCRIPTION, EXPIRY_DT, 
        LAST_UPDATE_DT, TX_LOG_IND, TX_OBJECT_TP, DEPRECATED_SINCE, DWL_PROD_TP_CD, 
        PARENT_BUSINESS_TX_TP_CD) 
      VALUES (1000055, 'addLivingThing',  null, null, CURRENT TIMESTAMP, 'Y', 'P', null, 1, 1000013);
    
    INSERT INTO CDBUSINESSTXTP (BUSINESS_TX_TP_CD, NAME, DESCRIPTION, EXPIRY_DT, 
        LAST_UPDATE_DT, TX_LOG_IND, TX_OBJECT_TP, DEPRECATED_SINCE, DWL_PROD_TP_CD, 
        PARENT_BUSINESS_TX_TP_CD) 
      VALUES (1000070, 'addPet',  null, null, CURRENT TIMESTAMP, 'Y', 'P', null, 1, 1000055);
  3. In CDINTERNALTXNTP table, set up the transaction relationship by PARENT_INTERNAL_BUS_TX_TP column. For example:
    Generated SQL for populating metadata: CDINTERNALTXNTP table
    INSERT INTO CDINTERNALTXNTP (INTERNAL_BUS_TX_TP, NAME, DESCRIPTION, EXPIRY_DT, 
        LAST_UPDATE_DT, COMPONENT_TYPE_ID) 
      VALUES (1000437, 'addSParty', null, null, CURRENT TIMESTAMP, 1000105);
    
    INSERT INTO CDINTERNALTXNTP (INTERNAL_BUS_TX_TP, NAME, DESCRIPTION, EXPIRY_DT, 
        LAST_UPDATE_DT, COMPONENT_TYPE_ID, PARENT_INTERNAL_BUS_TX_TP) 
      VALUES (1000446, 'addLivingThing', null, null, CURRENT TIMESTAMP, 1000147, 1000437);
    
    INSERT INTO CDINTERNALTXNTP (INTERNAL_BUS_TX_TP, NAME, DESCRIPTION, EXPIRY_DT, 
        LAST_UPDATE_DT, COMPONENT_TYPE_ID, PARENT_INTERNAL_BUS_TX_TP) 
      VALUES (1000440, 'addHuman', null, null, CURRENT TIMESTAMP, 1000121, 1000446);
  4. If a transaction participates in the entity subtyping framework, create its metadata for table INTERNALTXREQRESP. This is a new table introduced in Master Information Hub, Version 9. For example, add the following metadata for addSParty:
    Listing 11. Generated SQL for populating metadata: INTERNALTXREQRESP table
    INSERT INTO INTERNALTXREQRESP (INTERNTX_REQRESP_ID, INTERNAL_BUS_TX_TP, APPLICATION,
        GROUP_NAME, REQ_RESP_IND, TX_PARAM_TP_CD, PARAM_NAME, PARAM_ORDER, 
        LAST_UPDATE_USER,LAST_UPDATE_DT, COLLECTION_IND)
    VALUES (1000460, 1000437, 'TCRM', 'SPartyBObj', 'I', null, null, 1, 'cusadmin', 
            CURRENT TIMESTAMP, null);
    
    INSERT INTO INTERNALTXREQRESP (INTERNTX_REQRESP_ID, INTERNAL_BUS_TX_TP, APPLICATION,
       GROUP_NAME, REQ_RESP_IND, TX_PARAM_TP_CD, PARAM_NAME, PARAM_ORDER,
       LAST_UPDATE_USER,LAST_UPDATE_DT, COLLECTION_IND)
    VALUES (1000461, 1000437, 'TCRM', 'SPartyBObj', 'O', null, null, null, 'cusadmin', 
            CURRENT TIMESTAMP, 'N');

Introduce an entity that contains instances of multiple types from a single type hierarchy

Business objects can contain other business objects that belong to the same type hierarchy. For example, CommunityBObj may contain one or more of the SPartyBObj, PetBObj, LivingThingBObj, and HumanBObj business objects or other extension subtyped business objects. Let's take a look at the best practices to support this requirement:

  • Introduce a setter and getter method for the root entity type in the container BObj. For example, introduce a getter and setter method for SPartyBObj in CommunityBObj:
    Listing 12. Introduce a getter and setter method for SPartyBObj in CommunityBObj
    public class CommunityBObj extends TCRMCommon  {
        protected Vector<SPartyBObj> vecSPartyBObj;
    
        public Vector getItemsSPartyBObj() {
          return vecSPartyBObj;
        }
    	
        public void setSPartyBObj(SPartyBObj sPartyBObj) {
          this.vecSPartyBObj.add(sPartyBObj);
        }
        ......
    }
  • In XSDs defining the RMI services, ensure that the element defined for SPartyBObj has the abstract attribute set to true. The element defined for the business object serving as a container for any of the subtypes of SParty (in this, case CommunityBObj) must refer to it using the ref attribute. Ensure that each entity in the type hierarchy has in its element definition a substitutionGroup attribute that is assigned the abstract element SPartyBObj. See the lines in bold in Listing 13.:
    Listing 13. XSDs: Introduce SPartyBObj as an abstract element
    <xsd:element name="SPartyBaseBObj" abstract="true" substitutionGroup="CommonBObj" 
         type="SPartyBaseBObjType"/>
    <xsd:complexType name="SPartyBaseBObjType" >
      <xsd:complexContent>
        <xsd:extension base="CommonBObjType"/>
      </xsd:complexContent>
    </xsd:complexType>
    
    <xsd:element name="CommunityBObj" substitutionGroup="CommonBObj" 
        type="CommunityBObjType" />
    <xsd:complexType name="CommunityBObjType">
    <xsd:complexContent>
    	<xsd:extension base="CommonBObjType">
    	<xsd:sequence>
    	 ......
    	 <xsd:element ref="SPartyBaseBObj" minOccurs="0" maxOccurs="unbounded"/>
    	 <xsd:element ref="TCRMExtension" minOccurs="0" maxOccurs="1"/>
    	 <xsd:element ref="PrimaryKeyBObj" minOccurs="0" maxOccurs="1"/>
       </xsd:sequence>
    </xsd:extension>
    </xsd:complexContent>
    </xsd:complexType>
    
    
    <xsd:element name="SPartyBObj" substitutionGroup="SPartyBaseBObj" 
        type="SPartyBObjType" />
    <xsd:complexType name="SPartyBObjType">
      <xsd:complexContent>
      <xsd:extension base="SPartyBaseBObjType">
      ......
    
    <xsd:element name="LivingThingBObj" substitutionGroup="SPartyBaseBObj" 
        type="LivingThingBObjType" />
    <xsd:complexType name="LivingThingBObjType">
      <xsd:complexContent>
      <xsd:extension base="SPartyBObjType">
      ......
    
    <xsd:element name="HumanBObj" substitutionGroup="SPartyBaseBObj" 
        type="HumanBObjType" />
    <xsd:complexType name="HumanBObjType">
      <xsd:complexContent>
      <xsd:extension base="LivingThingBObjType">
      ......

Create extension subtypes and data extensions on subtyped entities

The case for extending or further subtyping an entity in a hierarchy as an extension is if, for example, you write your application and intend for your customers or clients to further extend the entities of your application. That is, there is no point in using either of these extension patterns when you have access to the source code of your application. This section focuses on this particular scenario.

For an existing entity type hierarchy, you might:

  • Further subtype any existing entity in the hierarchy
  • Extend a leaf entity in the hierarchy

For example, a further subtype Male can be introduced under Human. You should follow the same steps described in the previous sections to implement this new subtype. Though services for Male reside in its own controller, they are able to be picked up by the entity subtyping framework when redirecting services. The class diagram in Figure 10 depicts the class relationships for the new subtype Male:

Figure 10. Class diagram for new subtype Male
This diagram depicts the major components impacted when further subtyping a leaf node of a type hierarchy. The MaleTxnBean transaction controller component class implements the MaleTxn interface. The addMale and updateMale services reside on this interface. The MaleFinder finder controller class implements the MaleFinder interface. The getMale service resides on this interface. The MaleComponent business component class extends from the Male interface. The addMale, updateMale, and getMale services that do all of the business logic behind the services reside on this interface. The MaleBObj business object class extends from the HumanBObj business object.

To extend a leaf entity in a type hierarchy (for example, to introduce XMaleBObjExt for MaleBObj), simply follow the standard data extension pattern provided by the InfoSphere Master Information Hub /MDM Server Workbench. (Note: As of Version 9.0, only leaf nodes more information on data extensions, please refer to the InfoSphere Master Information Hub or MDM Server Developer's Guide.


Conclusion

This tutorial introduced the concept of entity subtyping. It discussed how to implement new and extension entity subtypes and related services for InfoSphere Master Information Hub and InfoSphere Master Data Management Server. You should have a better understanding of this method of achieving service interoperability and extensibility for a new domain created using Master Information Hub. You should also understand the possibilities you have for customizing the implementation of subtyped entities and their services.

Acknowledgement

The authors would like to thank their colleagues Paul van Run and Lena Woolf for their valuable suggestions and feedback on this tutorial.

Resources

Learn

Get products and technologies

  • Build your next development project with IBM trial software, available for download directly from developerWorks.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Information management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Information Management
ArticleID=464866
ArticleTitle=Introducing entity subtypes in IBM InfoSphere Master Information Hub
publish-date=01282010