7

Is there any easy way to clear the cache for a custom entity? I know there is an entry in the cache_entity-Table. If i manually delete it, everything is fine. I tried doing the same as in \Drupal\Core\Entity->invalidateTagsOnSave() or \Drupal\Core\Entity->invalidateTagsOnDelete(). This does not seem to change anything.

Unfortunately I can't just load the entity and resave it in this situation.

1
  • Are you adding any cache tags or contexts or data to the entity itself?
    – Kevin
    Commented Feb 9, 2018 at 20:21

3 Answers 3

16

But you know the entity ID that you want to have invalidated?

Then use \Drupal::entityTypeManager()->getStorage($entity_type_id)->resetCache([$id]);

5
  • 1
    that works like charm, but why Cache::invalidateTags($tags) does not work?
    – David
    Commented Jun 15, 2020 at 13:34
  • 1
    because the entity storage doesn't use cache tags.
    – Berdir
    Commented Jun 26, 2020 at 8:11
  • is it useful when we render result in blocks? cause not working for me Commented Oct 26, 2020 at 11:05
  • 3
    I found that you need to combine this statement with the statement below in order to fully reset cache: \Drupal\Core\Cache\Cache::invalidateTags($entity->getCacheTagsToInvalidate()); Commented Apr 21, 2021 at 2:51
  • @Berdir would clearing the cache for entity that's being edited cause any issues? or that's only for the form cache?
    – awm
    Commented Oct 13, 2022 at 18:58
6

To invalidate a cache you should use the Drupal cache invalidator service : cache_tags.invalidator.

Static call

// Invalide a Node cache.
\Drupal::service('cache_tags.invalidator')->invalidateTags(['node:5']);
// Invalidate a custom entity cache.
\Drupal::service('cache_tags.invalidator')->invalidateTags(['custom_entity:5']);
// Invalidate a custom cache tag.
\Drupal::service('cache_tags.invalidator')->invalidateTags(['thing:identifier']);

Dependency injection call

my_module.services.yml

services:
  hello.service:
    class: \Drupal\my_module\Service\Hello
    arguments:
      - '@cache.default'
      - '@cache_tags.invalidator'

Hello.php


use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheTagsInvalidator;

class Hello {

 /**
   * Cache backend.
   *
   * @var Drupal\Core\Cache\CacheBackendInterface
   */
  protected $cacheBackend;

 /**
   * Cache tags invalidator.
   *
   * @var Drupal\Core\Cache\CacheTagsInvalidator
   */
  protected $cacheInvalidator;

  /**
   * {@inheritdoc}
   */
  public function __construct(
    CacheBackendInterface $cacheBackend,
    CacheTagsInvalidator $cacheInvalidator
  ) {
    $this->cacheBackend = $cacheBackend;
    $this->cacheInvalidator = $cacheInvalidator;
  }
  
  /**
   * Function getting something from cache.
   */
  public function getSomething() {
    $cid = 'thing:identifier';
    $data = NULL;
    $cache = $this->cacheBackend->get($cid);

    if ($cache) {
      $data = $cache->data;
    }
    else {
      $data = my_module_complicated_calculation();
      $this->cacheBackend->set(
        $cid,               // Cache tag identifier.
        $data,              // Data to store in cache.
        Cache::PERMANENT,   // Save permanently.
        ['node:5', 'user:7']// Automatically invalidated if these entities are modified.
      );
    }

    return $data;
  }
  
  /**
   * Function invalidating a cache tag.
   */
  public function invalidateSomething() {
    $cid = 'thing:identifier';
    $this->cacheInvalidator->invalidateTags([$cid]);

    return;
  }
}    

Links

3

In your custom entity you should override the function

public function getCacheTagsToInvalidate();

of the EntityInterface.

Then, to clear that entity's cache you simply call

\Drupal\Core\Cache\Cache::invalidateTags($entity->getCacheTagsToInvalidate());

If you do not override getCacheTagsToInvalidate() the default implementation in entity.php should also work:

public function getCacheTagsToInvalidate() {
    if ($this->isNew()) {
      return [];
    }
    return [$this->entityTypeId . ':' . $this->id()];
  }

The tags[] is just the name plus the id.

2
  • 1
    Will this also invalidate the {entity_type_id}_list tag? Commented Nov 26, 2018 at 23:37
  • It's your custom entity. If your cache on the {entity_type_id}_list tag depends on a single instance, then add this tag to your getCacheTagsToInvalidate() return array. Commented Nov 27, 2018 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.