diff --git a/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php b/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php
index 1530693..be3fe15 100644
--- a/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php
+++ b/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php
@@ -66,7 +66,8 @@ public function access(EntityInterface $entity, $operation, AccountInterface $ac
       $operation = 'view';
     }
 
-    if (($return = $this->getCache($entity->uuid(), $operation, $langcode, $account)) !== NULL) {
+    $cid = $this->getCacheId($entity);
+    if (($return = $this->getCache($cid, $operation, $langcode, $account)) !== NULL) {
       // Cache hit, no work necessary.
       return $return_as_object ? $return : $return->isAllowed();
     }
@@ -92,7 +93,7 @@ public function access(EntityInterface $entity, $operation, AccountInterface $ac
     if (!$return->isForbidden()) {
       $return = $return->orIf($this->checkAccess($entity, $operation, $account));
     }
-    $result = $this->setCache($return, $entity->uuid(), $operation, $langcode, $account);
+    $result = $this->setCache($return, $cid, $operation, $langcode, $account);
     return $return_as_object ? $result : $result->isAllowed();
   }
 
@@ -180,6 +181,29 @@ protected function getCache($cid, $operation, $langcode, AccountInterface $accou
   }
 
   /**
+   * Generates a cache identifier for the entity.
+   *
+   * @param EntityInterface $entity
+   *   The entity for which to generate an identifier.
+   *
+   * @return string
+   *   The cache identifier.
+   */
+  protected function getCacheId(EntityInterface $entity) {
+    $cache_key = [
+      $entity->uuid(),
+      $entity->language()->getId()
+    ];
+    if ($entity instanceof EntityChangedInterface) {
+      $cache_key[] = $entity->getChangedTime();
+    }
+    if ($entity instanceof RevisionableInterface) {
+      $cache_key[] = $entity->getRevisionId();
+    }
+    return hash('sha256', implode('.', $cache_key));
+  }
+
+  /**
    * Statically caches whether the given user has access.
    *
    * @param \Drupal\Core\Access\AccessResultInterface $access
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index cf1a63c..819a7a7 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -759,6 +759,13 @@ function entity_test_entity_access(EntityInterface $entity, $operation, AccountI
     return AccessResult::allowed();
   }
 
+  if ($entity->label() == 'Accessible') {
+    return AccessResult::allowed();
+  }
+  if ($entity->label() == 'Inaccessible') {
+    return AccessResult::forbidden();
+  }
+
   // Uncacheable because the access result depends on a State key-value pair and
   // might therefore change at any time.
   $condition = \Drupal::state()->get("entity_test_entity_access.{$operation}." . $entity->id(), FALSE);
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityAccessControlHandlerTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityAccessControlHandlerTest.php
index 77210d5..46900d6 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityAccessControlHandlerTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityAccessControlHandlerTest.php
@@ -200,6 +200,32 @@ function testEntityTranslationAccess() {
   }
 
   /**
+   * Ensures the static access cache does not go stale when entities change.
+   */
+  function testEntityAccessCache() {
+    $account = $this->createUser();
+
+    // Save a new entity. entity_test_entity_access() will make it accessible
+    // based on the label.
+    $entity = EntityTest::create(array(
+      'name' => 'Accessible',
+    ));
+    $entity->save();
+
+    $this->assertEntityAccess(array(
+      'view' => TRUE,
+    ), $entity, $account);
+
+    // Save the entity again. entity_test_entity_access() makes it inaccessible.
+    $entity->name->value = 'Inaccessible';
+    $entity->save();
+
+    $this->assertEntityAccess(array(
+      'view' => FALSE,
+    ), $entity, $account);
+  }
+
+  /**
    * Tests hook invocations.
    */
   public function testHooks() {
