A massive VBO update on field collections throws the following error:

Exception: The host entity cannot be changed. in FieldCollectionItemEntity->updateHostEntity()

This error is triggered by the same exception as in #2382089: Logic issue with fetchHostDetails() causes false "the host entity cannot be changed" error in updateHostEntity(), but its cause is different:

While trying to update multiple entities with VBO, the $items array is updated by each call of field_collection_field_update() and therefore keeps track of last updated entity in $item['entity']. But this is needed for hook_field_update() to work.

/**
 * Implements hook_field_update().
 */
function field_collection_field_update($host_entity_type, $host_entity, $field, $instance, $langcode, &$items) {
  ...
  foreach ($items as &$item) {
  ...
    if ($entity = field_collection_field_get_entity($item)) {
      ...
        $item = array(
          'value' => $entity->item_id,
          'revision_id' => $entity->revision_id,
        );

This causes $entity = field_collection_field_get_entity($item) to use the previous field collection item_id and revision_id, and therefore $entity->fetchHostDetails() will always get as host the first updated entity, hence the exception with if ($current_id == $recieved_id) in updateHostEntity($entity)

The solution is to reset the $item entity on every call to field_collection_field_update():

$values = array_merge($item, array('field_name' => $item['entity']->field_name));
$item['entity'] = entity_create('field_collection_item', $values);

if ($entity = field_collection_field_get_entity($item)) {

And now it works, for single values, or for massive updates with VBO.

Note that this causes each update to create a new item id and revision id, but it's actually already the case with a single value. The field collection doesn't get updated, a new one is created and the old one deleted.

Attached the patch.

Comments

wayaslij created an issue. See original summary.

adrien.felipe’s picture

caspervoogt’s picture

will test this out next time I run into VBO/field collection errors.

lakshminp’s picture

Patch #2 worked for me.

adrien.felipe’s picture

Be aware patch#2 will prevent you from using field_collection->save to update field collections programmatically.

michiellucas’s picture

Problem with the patch above is that when you save the node where the field collection is attached every time a new field collection is created.

michiellucas’s picture

Created new patch that checks if we need to fix the host entity problem

adrien.felipe’s picture

Empty post to increment comment number to 9.

adrien.felipe’s picture

Thanks for the patch correction @michiellucas.
I had to re-roll it as it was not a p1 patch (you built it from your doc root)
I'll give it a try.

michiellucas’s picture

My bad, it was Friday :d

Anonymous’s picture

StatusFileSize
new529 bytes

I came up with an alternative approach to ensure we don't have new items created when not VBO'ing, and not updating the original field on the entity VBO uses - clone $item['entity'] in field_collection_field_get_entity() so we're never touching the original when we do the save.

Looking at all calls to field_collection_field_get_entity() in the field_collection module, none of them ever make changes that need to be kept on that initial $item['entity'] object.

adrien.felipe’s picture

Thanks @rsmylski, patch #11 seems to work fine.

BD3’s picture

Status: Active » Needs review

#11 worked great for me too.

nimek’s picture

Status: Needs review » Reviewed & tested by the community

patch #9 works - mark issue as RTBC

Anonymous’s picture

Status: Reviewed & tested by the community » Needs review

As a follow up, the patch in #9 does not work. It does stop the error from happening with VBO actions, but it broke a few of our sites, when saving (updating) normal field collections - I would always get a new item saved, the original would never get updated. My patch in #11 addresses that issue.

Marking back as needs review, as there needs to be more feedback that the patch doesn't effect anything else.

nimek’s picture

@rsmylski

Sorry my mistake. I have tested patch #11 not #9 and it works great.
So If you want you can get back to RTBC.

etron770’s picture

Seems that there is another issue
if you have Field Group enabled ( https://www.drupal.org/project/field_group )

and
Field Tabs group_field_tabs
-- horzontal tab1
------ field_Tab1_group
-- horzontal tab2
------ field_Tab2_group

it is impossible to edit and save both horizontal tab fieldgroups without getting
Exception: The host entity cannot be changed. in FieldCollectionItemEntity->updateHostEntity()
line 239 from sites/all/modules/field_collection/field_collection.entity.inc).

and I have one item which is impossible to edit in anyway

FYI: Its an extended commerce kickstart installation with 265 active modules, so it might be difficult to find out whats the reason

etron770’s picture

Patch #11 is working with for #17
further test will follow when site will be filled with content

jmuzz’s picture

Status: Needs review » Postponed (maintainer needs more info)

it's actually already the case with a single value. The field collection doesn't get updated, a new one is created and the old one deleted.

That shouldn't be the case. When does it do this?

Is there a way to fix the error without creating new field collection items during every edit?

adrien.felipe’s picture

@jmuzz as far as I recall, debuging while updating with VBO would create a new field collection ID, wihtout any patch applied.
If it's not the case anymore, patch #11 should not create a new field collection either.

moonray’s picture

Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new1.04 KB

It seems that someone the hostEntityId is not set properly in some cases. Attached patch fixes it by checking for an empty hostEntityId in addition to checking isInUse().
I've left the clone() code from patch #11 as well.

Status: Needs review » Needs work
etron770’s picture

Final report for #18
The website is online with patch #11 and full content no problems

nimek’s picture

I also tested patch #11 on live site with field group and no problems. I will mark it as NR.

nimek’s picture

Status: Needs work » Needs review
judapriest’s picture

With 7.x-1.0-beta12+4-dev Patch #11 didn't work for me.

With 7.x-1.0-beta12+4-dev Patch #21 did work for me.
But the test failed on local too.

jcisio’s picture

StatusFileSize
new1.23 KB
new1.17 KB

Patch #21 does not work with Migrate (destid1 = NULL in the map table). Here is a new patch.

joelpittet’s picture

Nit: clone is not a function, doesn't need the parenthesis.

adrien.felipe’s picture

Is it not a little bit risky to assume it's VBO when count($item) > 1 ?
Just asking. We probably have no other choice.

Anonymous’s picture

@jcisio - what were you experiencing with migrate that lead to adding the count($item) > 1? I don't see why always returning the clone of $item['entity'] would be problematic.

cayenne’s picture

I have just run into this problem on my own site.

Looking at the database, it seems that one need change only two values in the relevant row to cause the field collection entity to have a new parent.

Specifically, in the table associated with the entity's field name (in my case, field_roster), change the values for entity_id and revision_id to conform to the new parent entity.

Seems like a short and simple function. It worked fine for me as a db command. Any reason it should not serve the purpose above?

jcisio’s picture

Re #30 @rsmylski: in migrate, it doesn't save the FC entity directly, but it save the parent entity. After that, it take the ID of FC entity to store in the map. When you clone the entity, the FC entity ID is set in the cloned, not in the original FC entity, therefore it won't work, because the original FC entity won't have an ID. I don't remember exactly (sorry I didn't see your questions), but that's what I meant in #27. To test, just try the patch #21 in any migration with FC, you'll see the problem.

Re #29: yes, unfortunately I don't know any better solution. Maybe we'd know when there are new bugs... I think we all know that there is no further development in this module, and it is better to use "standalone" entities instead of dependant "faked" entities like FC, so they are workaround to help other users from losing their time.

ElemAm024’s picture

Patch in #27 for beta-12 works perfectly for me. Thank god, I was tearing my hair out trying to debug on my own!

jdleonard’s picture

Latest dev + #27 resolved the exception I was encountering:

The host entity cannot be changed. in FieldCollectionItemEntity->updateHostEntity()`

However, VBO had nothing to do with my error. I suspect my use of the Revisioning module (or possibly just Entity API revisions) was the cause. The steps to reproduce this for me (prior to applying #27) were:

  1. Create node (containing a Field Collection) in unpublished state.
  2. Submit node edit form (making changes is not necessary).
  3. Submit node edit form a second time (making changes is not necessary).
msningrum’s picture

I am wondering if the patch here is specifically to resolve the issue related to VBO, but I am experiencing this issue when I import content with field collection values using node_export module. Patch #27 against 7.x-1.0-beta12 doesn't resolve this issue.

jomarocas’s picture

Status: Needs review » Reviewed & tested by the community

I try the patch #27 with the latest dev of field_collection beta12+dev and working good, create new items with VBO and save the value, for me testing good and solution a big problem that i have.

try following drush dl field_collection --dev

  • ram4nd committed d2e9b0f on 7.x-1.x authored by jcisio
    Issue #2658882 by adrien.felipe, jcisio, rsmylski, michiellucas, moonray...
ram4nd’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

kengilb’s picture

Re-rolling #11 for 7.x-1.0-beta13.