Friday, November 1, 2013

About your elements Origin, ID and Handle

This post will be about the elements Origin, their ID and finally the Handle. These are important to grasp as AX developer when creating elements in the Application Object Tree (AOT) and copying them around between environments. I hope it will help both new and old AX developers.

The Origin is made up of a Global Unique ID (GUID), and it will follow the element created throughout its lifetime, from the very first brilliant idea, through all sorts of versions and bug fixes and until is is one day obsoleted; from cradle to grave. This Origin will be the same for this element in all installations, environments, versions and variations. It is unique and special, and it so for a purpose.

Take this table as an example:



The Origin of this table will follow this table from my development environment and into any other installation. If I copy this table using XPO, Model or ModelStore, this is the Origin it will carry everywhere. This also means that if I create "MyTable" in my AX, and you create your "MyTable" in your AX, you can be certain they will have different Origin, and essentially not be the same table.

Take a look at how the Origin is part of the element description when I export it to a XPO.


The same is true if I make an axmodel-file having this table.

So why is this so important? Well, most seasoned Dynamics AX developers have at some point gotten their hands burned on element ID conflict, element cache become invalid, change of element ID causing loss of data and so on. AX 2012 attempts to solve this by letting us forget about element ID altogether and instead focus on Origin. The goal is for us developers only to worry about Origin as identification of Elements.

Great, but what is "Element ID"? Element ID is a unique number identifying elements in the AOT. This ID is used a lot in AX for historical and good reasons. It is a way for the system to quickly identify any element for things like indexing, cache, relations, usage, etc. It works like charm, and is a lot more efficient than using the actual name, path or some other non-numeric reference to the element. Surely a GUID is not a very efficient way to index and organize a long list of elements - just think about it.

Element ID comes into play as soon as en element is created in the AOT, but an important difference compared to the Origin is the fact that the Element ID may perfectly well be different between environments. Element ID is strongly tied to the business data, so if the Element ID is changed or made invalid, you risk loss of data. There are however ways around this, but they are not discussed in this post.

Let us have a look at how Origin works when Elements get their ID in AX during import of a XPO or installation of a Model (axmodel). Details can be found in this Technet Article.


The system will automatically try to reuse Element ID based on Origin, or it will create a new Element ID if necessary. There is also this LegacyID, which is a way to make some IDs backward compatible with previous versions of AX, if really necessary.

As an example, take a look at good old CustTable, number 77. :-)


Also take notice of the Origin and compare it to the Origin in your AX environment. Is it the same? It sure is!

Ok, so what is then Element Handle? It is unique ID identifying every single element in the AOT that is meant to be uniquely identified. It is also the ID being used as key and foreign key in the tables containing the information about the AOT elements (ModelElement, ModelElementData, etc). The system assigns Element Handles just as it does RecIds.

Does that mean Origin and Element ID doesn't cover all possible elements in identifying them? The answer is NO! Take table methods as an example. It does not have an Origin, nor does it have en Element ID. It does have en Element Handle.

Try run the SQL underneath in your AX environment and see what handles you have for CustTable and a custom table.

SELECT ELEMENTHANDLE, ROOTHANDLE, NAME, AXID, ORIGIN FROM MODELELEMENT 
JOIN ELEMENTTYPES ON MODELELEMENT.ELEMENTTYPE = ELEMENTTYPES.ELEMENTTYPE
WHERE NAME IN ('CUSTTABLE', 'MYTABLE') AND ELEMENTTYPENAME IN ('TABLE')



You may want to replace "MyTable" with a custom table of your own. Notice how my ElementHandle of CustTable differs from yours.

So let's wrap this up with some highlights:
  • Origin is your cradle to grave ID for your new Elements. It is the only ID you really need to worry about.
  • Element ID works pretty much like before, except you no longer keep it between environments. System creates this ID uniquely for you.
  • Element Handles uniquely identifies every single identifiable element in the AOT and is provided by the system.
  • Not all elements have Origin or Element ID, but all elements have a Handle.
  • Finally - Business data is tied to Element ID and not Origin. Don't ever get tempted to mix one modelstores business data with another modelstores business data.
If you ever wonder what elements have ElementHandle but no Origin or ElementID (AxID), you could try run these queries on your modelstore database:

-- Get all element types having Origin but no Element ID
SELECT DISTINCT ELEMENTTYPES.ELEMENTTYPENAME
 FROM MODELELEMENT JOIN ELEMENTTYPES ON MODELELEMENT.ELEMENTTYPE = ELEMENTTYPES.ELEMENTTYPE
 WHERE AXID IN (0) AND ORIGIN NOT IN ('00000000-0000-0000-0000-000000000000') 
 
-- Get all element types having no Origin 
SELECT DISTINCT ELEMENTTYPES.ELEMENTTYPENAME
 FROM MODELELEMENT JOIN ELEMENTTYPES ON MODELELEMENT.ELEMENTTYPE = ELEMENTTYPES.ELEMENTTYPE
 WHERE ORIGIN IN ('00000000-0000-0000-0000-000000000000') 

Thank you for reading!