Searching for REAL orphans in Enterprise Architect

Enterprise Architect comes standard with an Find Orphans search, which is supposed to give you a list of all elements that are no longer used in the model, and thus better be removed from the model altogether.

Find Orphans

The problem with this search is that it will only report elements that are not shown on a diagram; which should not be the only criterion to determine if an element is an orphan or not. Not being on a diagram is just fine. I have lots of elements in my model that are not on a diagram, that doesn’t mean they are not used anymore.

If you are going to delete all elements reported in the standard orphans search you might do serious damage to your model.

So in order to aid with the maintenance of a large model I wrote the following SQL Search.

select distinct o.ea_guid as CLASSGUID,o.Object_Type as CLASSTYPE,o.Name as Name, o.Stereotype, as PackageName , as PackageLevel1, as PackageLevel2 , as PackageLevel3 
from ((((((((((((((((( t_object o
left join t_diagramobjects dob on dob.[Object_ID] = o.[Object_ID])
left join t_object inst on inst.[Classifier] = o.[Object_ID])
left join t_objectproperties otv on otv.VALUE = o.[ea_guid])
left join t_connectortag ctv on ctv.VALUE = o.[ea_guid])
left join t_attributetag atv on atv.VALUE = o.[ea_guid])
left join t_operationtag optv on optv.VALUE = o.[ea_guid])
left join t_object u on u.Pdata1 = o.ea_guid)
left join t_connector cs on cs.Start_Object_ID = o.Object_ID)
left join t_connector ce on ce.End_Object_ID = o.Object_ID)
left join t_attribute att on att.Classifier like o.Object_ID)
left join t_operation op on op.Classifier like o.Object_ID)
left join t_operationparams opp on opp.Classifier like o.Object_ID)
left join t_object owned on owned.ParentID = o.Object_ID)
inner join t_package package on o.package_id = package.package_id) 
left join t_package package_p1 on package_p1.package_id = package.parent_id) 
left join t_package package_p2 on package_p2.package_id = package_p1.parent_id) 
left join t_package package_p3 on package_p3.package_id = package_p2.parent_id) 
o.Package_ID in (#Branch#)
and ( is null or o.Name like '#WC#<Search Term>#WC#')
and o.Object_Type not in ('Package')
and (o.Stereotype is null or o.Stereotype not in ('model document'))
and dob.Object_ID is null
and inst.Object_ID is null
and otv.VALUE is null
and ctv.Value is null
and atv.Value is null
and optv.Value is null
and u.Object_ID is null
and cs.Start_Object_ID is null
and ce.End_Object_ID is null 
and att.Classifier is null
and op.Classifier is null
and opp.Classifier is null
and owned.Object_ID is null

This search will look for all elements that

  • Are located in the currently selected package branch
  • Are not a package or a model document  (section in a virtual document)
  • Are not used on a diagram
  • Are not used as the Classifier of an instance
  • Are not referenced by any tagged value
  • Are not used as the source or target of any relation
  • Are not used as the type of an attribute
  • Are not used as the return type of an operation
  • Are not used as the type of a parameter
  • Do not own any other elements

Elements that show up in this search are most probably real orphans that clutter your model and can be safely deleted.

Of course, before you delete anything from the model, make sure you have a backup!

Find Real OrphansIn order to use this search create a new search of type SQL and paste the above query into the query builder field.

If you find anything that should be added to this search please let me know.


2 replies
  1. Marc Vanstraelen
    Marc Vanstraelen says:

    Geert, this is quite useful. However, when I use it on some of our models, it returns some activities that are parent to a (non-empty) diagram.(but the elements on the diagram are not under that activity).


Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.