This was a stumper, but I'm working on a site which has a rather convoluted migration system where we're migrating things from several XML files, one at a time, so a node might be updated with each "pass." One doesn't update nodes directly, but instead migrates values into field collection entities. We've been frustrated for days by bugs where new data just sucked into the nodes via a migration would end up reset back to old values at the end of the migration. I finally traced it down to FieldCollectionItemEntity::fetchHostDetails(), which seems all too happy to load an old revision of the host for some reason, then save it down the migration road.

Here's a workaround I found that doesn't involve patching Field Collection; a prepare method on the migration class which has the field collection as the destination which looks something like this:

  public function prepare($entity, $row) {
    parent::prepare($entity, $row);
    // The field collection migration code will have loaded an old revision of
    // the host entity; when it saves the host entity, old field values will
    // overwrite the current ones. Set the most recent revision as the host
    // entity instead.
    if ($hosts = entity_load($entity->hostEntityType(), array($entity->hostEntityId()))) {
      $host = reset($hosts);
      $entity->updateHostEntity($host);
    }
  }

Comments

roi’s picture

Thanks, Garrett, your workaround worked for me.
One thing, though, it had to change: I couldn't use the line

parent::prepare($entity, $row);

because then I would get an error:

PHP Fatal error:  Call to undefined method TammuzMigration::prepare() in /home/roi/git/crm_drupal_modules/drupal/modules/migrate/migrate_tammuz/migrations/instant_messaging.inc on line 50

do you know why?

Garrett Albright’s picture

roi, it sounds like your migration class's parent class(es) simply doesn't have a prepare() method. In that case it should be fine to omit that line.

Be forewarned that I've found a lot of other quirks with Field Collection's Migrate support. If you notice something odd in the behavior of one of your migrations that has something to do with FCs, try debugging the FC part first. :)