Handling circular entity references with Migrate I am using Migrate D2D on a Drupal 6 to Drupal 7 migration right now.

I have three types: type1, type2, type3.  Each of the three types has a entityreference field on it, which is configured to be able to point to all three types.  This means that there can be circular references, and when a particular node is being migrated, the destination node may not exist yet and could potentially be any of the three types.

My migration class looks like this:

class MyNodeMigration extends DrupalNode6Migration {
  public function __construct(array $arguments) {
    parent::__construct($arguments);

    $this-&gt;addFieldMapping('field_legacy_nid', 'nid');

    $this-&gt;addFieldMapping('field_the_reference', 'field_the_reference')
      -&gt;sourceMigration(array('type1', 'type2', 'type3');
  }
}

$node_arguments = array(
  array(
    'class_name' =&gt; 'MyNodeMigration',
    'description' =&gt; 'type1',
    'machine_name' =&gt; 'type1',
    'source_type' =&gt; 'type1',
    'destination_type' =&gt; 'type1',
    'dependencies' =&gt; array('roles', 'users'),
  ),

  array(
    'class_name' =&gt; 'MyNodeMigration',
    'description' =&gt; 'type2',
    'machine_name' =&gt; 'type2',
    'source_type' =&gt; 'type2',
    'destination_type' =&gt; 'type2',
    'dependencies' =&gt; array('roles', 'users'),
  ),

  array(
    'class_name' =&gt; 'MyNodeMigration',
    'description' =&gt; 'type3',
    'machine_name' =&gt; 'type3',
    'source_type' =&gt; 'type3',
    'destination_type' =&gt; 'type3',
    'dependencies' =&gt; array('roles', 'users'),
  ),
);

$common_node_arguments = $common_arguments + array(
  'user_migration' =&gt; 'users',
);

foreach ($node_arguments as $arguments) {
  $arguments = array_merge_recursive($arguments, $common_node_arguments);

  Migration::registerMigration($arguments['class_name'], $arguments['machine_name'], $arguments);
}


When I run the migrations, most nodes are fine, but I get a decent amount of Stubs (*) created.  Some of the destination nodes have the entityreference pointing to these Stub nodes.  The source nodes are fine.

What I have uncovered is that the bundle on the destination nodes that are being made as stubs are incorrect, and look like they are all type1.  A node of the proper type does end up being created, but it never gets set as the entityreference target.

Another way to explain this is that I end up with


node: nid=123, type=type1
node: nid=234, type=type1, field_the_reference=123
node: nid=345, type=type2


where it should be


node: nid=234, type=type1, field_the_reference=345
node: nid=345, type=type2


How do I handle this situation?

(*): a "Stub" in the context of this question here refers to a node which is created for the purpose of being a reference target, but does not get its data initially. The term is used throughout the Migrate documentation and source code.
The main problem has to do with how stubs are handled in Migrate, and is related to a known issue.

In short, when the destination can be one of several content types, the migration doesn't know what content type to create the stub as in a generic way.

My current workaround for this is to prevent stubs from being created:

abstract class MyNodeMigration extends DrupalNode6Migration {
  ... 

  protected function createStub(Migration $migration, array $source_id) {
    return FALSE;
  }
}


When the migration runs, stubs don't get created, but the entity reference fields in my destinations also don't get populated.

I then manually reset the highwater mark

db_update('migrate_status')
  -&gt;fields(array('highwater' =&gt; 0))
  -&gt;condition(...)
  -&gt;execute();


and then rerun the migrations.  Since the destination nodes exists, the entity reference fields can be populated properly.