In latest Drupal9/Drupal10 entity bundle field map was moved from being generated on demand and cached to being saved in the key value store.
This data is being managed in the FieldDefinitionListener::onFieldDefinitionCreate() and FieldDefinitionListener::onFieldDefinitionDelete() methods. But there is a problem - only data related to specific field (which is being updated or deleted) is updating with the above methods.
Sometimes entity bundle field map could go out of sync – in case of fields machine names changes or some other custom not very straightforward manipulations. That creates tons of annoying errors in logs. So while core issue is still in progress here is the snippet to rebuild bundle field map in hook_post_update_NAME or hook_deploy whatever:
use Drupal\Core\Entity\FieldableEntityInterface;
/**
* Rebuild the entity bundle field map.
*/
function custom_module_deploy_rebuild_entity_bundle_field_map() {
$entity_bundle_info = \Drupal::service('entity_type.bundle.info');
$entity_type_manager = \Drupal::service('entity_type.manager');
$entity_field_manager = \Drupal::service('entity_field.manager');
$map = [];
foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) {
if (!$entity_type->entityClassImplements(FieldableEntityInterface::class)) {
continue;
}
foreach ($entity_bundle_info->getBundleInfo($entity_type_id) as $bundle => $bundle_info) {
foreach ($entity_field_manager->getFieldDefinitions($entity_type_id, $bundle) as $field_name => $field_definition) {
if (!$field_definition->getFieldStorageDefinition()->isBaseField()) {
$map[$entity_type_id][$field_name]['type'] = $field_definition->getType();
$map[$entity_type_id][$field_name]['bundles'][$bundle] = $bundle;
}
}
}
}
$persistent_map = \Drupal::keyValue('entity.definitions.bundle_field_map');
$persistent_map->setMultiple($map);
}