Previously we have been able to turn off entity caching by using either hook_entity_type_alter() or hook_entity_type_build() by doing the following:
/**
* Implements hook_entity_type_alter().
*/
function MY_MODULE_entity_type_alter(array &$entity_types) {
$entity_types['ENTITY_TYPE_ID']->set('static_cache', FALSE);
$entity_types['ENTITY_TYPE_ID']->set('persistent_cache', FALSE);
$entity_types['ENTITY_TYPE_ID']->set('render_cache', FALSE);
}
This process no longer works in 8.7.x or 8.8.x since the introduction of entity type definitions now having the ability to be "loaded from code" and also the ability to get "the active definitions" in issue 2554235: Make the content entity storage and entity query use the last installed definitions instead of the ones living in code
The issue now is that depending on how the entity type object is retrieved, we will get different results.
For instance if we want to just turn off persistent caching on nodes, we would do the following:
/**
* Implements hook_entity_type_alter().
*/
function MY_MODULE_entity_type_alter(array &$entity_types) {
$entity_types['node']->set('persistent_cache', FALSE);
}
But this will not turn off persistent caching for nodes, as the following would indicate.
/** @var \Drupal\Core\Entity\EntityTypeManager $entity_type_manager */
$entity_type_manager = Drupal::service('entity_type.manager');
// The node's entity type when loaded "from code".
$is_cachable_1 = $entity_type_manager->getDefinition('node')->isPersistentlyCacheable();
// The node's entity type when loaded "from active".
$is_cachable_2 = $entity_type_manager->getActiveDefinition('node')->isPersistentlyCacheable();
// The node storage's entity type object is loaded "from active".
$is_cachable_3 = $entity_type_manager->getStorage('node')->getEntityType()->isPersistentlyCacheable();
// Node is ultimately loaded from persistent cache (if previously loaded)
// since load() uses the entity type object from the SqlContentEntityStorage
// class. This can be proven to load from cache by putting a breakpoint
// in \Drupal\Core\Entity\Sql\SqlContentEntityStorage::doLoadMultiple().
$node = Node::load(1);
// Yet the loaded node's entity type object is loaded "from code".
$is_cachable_4 = $node->getEntityType()->isPersistentlyCacheable();
// Results:
// $is_cachable_1 === FALSE
// $is_cachable_2 === TRUE
// $is_cachable_3 === TRUE
// $is_cachable_4 === FALSE
Is there an official way to modify an existing entity type to disable caching (or perform other modifications) besides using hook_entity_type_alter() or hook_entity_type_build()?
Comments
Comment #2
mdolnik commentedNote: A temporary work-around could be achieved by calling
EntityLastInstalledSchemaRepository::setLastInstalledDefinition()in the entity-type-alter hook after modifying the entity type...But I don't think this is the best way to go about getting the
hook_entity_type_alter()approach to work, as this is skirting the entity type alter process by manually updating the latest installed definition.If anything I beleive the entity-type-alter process itself should be doing this behind the scenes in core after all of the entity-type-alter hooks are called and prior to caching the built definitions.
Thoughts?
Comment #3
alexpottThis is fixed by #3124830: Fix project on Drupal ^8.7 and fix failing tests on 8.x-2.x
Comment #4
alexpott