How to detect a circular reference in a hierarchy table?
Here's a thought:


Add a column depth SMALLINT UNSIGNED NOT NULL DEFAULT '0'
Repeatedly bump depth to be at least 1 more than the parent:

UPDATE MyTable AS child
  JOIN MyTable AS parent ON child.ParentId = parent.Id
  SET child.depth = GREATEST(child.depth, parent.depth + 1)
  WHERE child.Id != 0;   -- the root says at depth=0
If rows affected drops to 0, you have no loops.
After awhile, any nodes in loop(s) will have large depth values.