≡ Menu

Bugs in TC’s Hierarchy of Types and Subtypes

Share the knowledge

I want to share some problems I’ve had with Teamcenter 8.3. I’ve come across two functions in Teamcenter 8.3 where I attempted to pass in the name of a base object type and expected the function to apply to all subtypes of that type, however the behavior was not inherited by the children types. I suspect there may be other examples of this problem waiting to be found.

EPM-validate-target-objects Doesn’t Apply to Subtypes

EPM-validate-target-objects is a workflow rule handler which allows you to check the targets submitted to a workflow and issue an error if the specified conditions are not met. In Teamcenter Engineering I would attach this handler to the start action of the root task to make sure that workflows for Item Revisions were not mistakenly invoked on an Item instead. I used the argument -allowed_type ItemRevision to do this, and any Item Revision, regardless of specific item type (e.g. Drawing Revision, Part Revision, etc.) would be valid, but anything else (Item, Folder, Dataset) would not.

I tried to use the same handler in Teamcenter 8.3, but I discovered that -allowed_type ItemRevision meant that only business objects specifically of type ItemRevision would be allowed. DesignRevision, PartRevision, and DrawingRevision would not. To me, this is a regression in functionality, and I know that mine is not the only customer IR that’s been filed with GTAC.

I presume that the problem is that the handler is specifically testing if the name of the underlying storage class matches “ItemRevision”, instead of doing a proper OO type inheritance check, “is DesignRevision a type of ItemRevision?”. In Teamcenter Engineering there was only one storage class for all item revisions, much like there’s only one storage class for all datasets now in Teamcenter 8, so the code would work no matter what the actual item type was.

I’m currently waiting to hear back from GTAC about if there’s a work-around or not.

[box type=”info”]
It turns out there’s a formal term for the expected behavior that’s being violated. The Liskov substitution principle, or LSP, defines substitutability in relation to object oriented programming as a desirable behavior. Substitutability is defined as, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may be substituted for objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).

Applying this principle to Teamcenter would mean that whatever behavior I expect when using an item revision should be the same behavior seen when using a subtype of item revision, such as design or drawing revision.


fnd0chkObjProp is an operation defined for ItemRevisions. Basically what it does is let you check if objects of a specified type that are attached to the revision with a specified relationship have a particular value or not.

The neat thing is that this is an item operation which you can call from a condition. My intention was to create a condition that used this operation to check if a revision had any checked-out specifications attached to it, so I passed in “IMAN_specification” and “WorkspaceObject” for my relation and object type parameters.

As you may have guessed, “WorkspaceObject” doesn’t work as I hoped it would. It turns out that I have to specify each object type I want to test for separately in its own call. So, Instead of,

has_checked_out_spec(ItemRevsion rev) :=
    rev.fnd0chkOjProp("IMAN_specification", "WorkspaceObject", 
                     "checked_out", "Y", true, "=")

to test if the rev has any workspace objects, attached as specifications, whose “checked_out” property is equal to “Y”, I need to do something more like this:

has_checked_out_spec(ItemRevision rev) := 
    rev.fnd0chkOjProp("IMAN_specification", "UGMASTER", 
                     "checked_out", "Y", true, "=")
    rev.fnd0chkOjProp("IMAN_specification", "UGPART", 
                     "checked_out", "Y", true, "=")
    // etc.

What Else?

Question for you: have you seen any other problems of this sort in Teamcenter 8? Leave a comment to share your experience.

  • Paul Nelson

    Not sure we have had a developer hit this in ITK, but we hit this in Java.  He found a new Java API that honored inheritence.  I would have to get with the developor to dig up details, but can do that if interested. 

    This subject ties to the BMIDE and your behavior will depend on your data model.  Your key question is, “is DesignRevision a type of ItemRevision?”.  The answer is it depends.  If the Design Revision is a primary business type in BMIDE it is NOT a type of ItemRevision.  If it is a secondary business type in BMIDE it IS a type of ItemRevision.  Primary vs. Secondary business object types might make an interesting post.  I have some charts on this if you are interested. 

    • http://plmdojo.com Scott Pigman

      Hi Paul, thanks for the comment, I really appreciate the contribution to the discussion. Good stuff, for sure.

      The thing is that it seems even your answer of, “it depends”, depends on the context. Example: Edit > Options > Item Revision > General, or Related Object. There, if you add a relation type to display under a particular type it will also show up under the subtypes.

      If a Design Revision is a primary Business object then it and Item Revision will have separate tables in the DB, but I believe that the UID for the Design Revision will be a primary key in both the Design and Item Revision tables, which is how Design Revisions inherit properties from Item revisions (disclaimer: I haven’t verified that this is how inheritance works in TCUA but it’s how class inheritance works in TcEng so I’m pretty confident it’s still done the same way.)

      The point being that since part of the data definition of Design Revision is in the the Item Revision table, it *is* an Item Revision — which conforms to how object oriented things are supposed to work.

      I think the real problem is that the implementations are simply doing a string comparison between the name of the business object submitted by the user and name of the table behind the scenes, instead of a proper type inheritance check, “isinstance(obj, class).”

      By the way, I re-wrote my article on the differences between Teamcenter classes and business objects and included some material on primary and secondary business objects this time.

      I would definitely like to see your charts and know more about the exact issue your developer hit.

  • Teamcenter Heretic

    I know this borders on a necro-post but in ITK I have always used this style of code (my Item class passes “Item” and the revision class passes “ItemRevision”).
    This code has always been rock solid for me and is still the case in 10.1

    bool PomObject::IsDescendent( const std::string & value) const
    logical bResult = TRUE;
    tag_t tagSeekingClass = NULLTAG;
    tag_t tagThisClass = NULLTAG;

    HNICHECK( POM_does_class_exist( value.c_str() , &bResult ) );
    if( TRUE==bResult )
    HNICHECK( POM_class_of_instance( GetTag() , &tagThisClass ) );
    HNICHECK( POM_class_id_of_class( value.c_str() , &tagSeekingClass ) );
    HNICHECK( POM_is_descendant( tagSeekingClass , tagThisClass , &bResult ) );
    std::cout << "Class " << value << "does not exist" << std::endl;
    return TRUE == bResult;

Optimization WordPress Plugins & Solutions by W3 EDGE