diff --git a/core/lib/Drupal/Core/Entity/EntityCreateAnyAccessCheck.php b/core/lib/Drupal/Core/Entity/EntityCreateAnyAccessCheck.php
index a6ff09430dd7285e2d50f07166b7b644787e1f20..e0e24a2f9ea200b9847234b7a644d71bbeba8c49 100644
--- a/core/lib/Drupal/Core/Entity/EntityCreateAnyAccessCheck.php
+++ b/core/lib/Drupal/Core/Entity/EntityCreateAnyAccessCheck.php
@@ -78,13 +78,15 @@ public function access(Route $route, RouteMatchInterface $route_match, AccountIn
     if ($entity_type->getBundleEntityType()) {
       $access->addCacheTags($this->entityTypeManager->getDefinition($entity_type->getBundleEntityType())->getListCacheTags());
 
-      // Check if the user is allowed to create new bundles. If so, allow
-      // access, so the add page can show a link to create one.
-      // @see \Drupal\Core\Entity\Controller\EntityController::addPage()
-      $bundle_access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type->getBundleEntityType());
-      $access = $access->orIf($bundle_access_control_handler->createAccess(NULL, $account, [], TRUE));
-      if ($access->isAllowed()) {
-        return $access;
+      if (empty($route->getOption('_ignore_create_bundle_access'))) {
+        // Check if the user is allowed to create new bundles. If so, allow
+        // access, so the add page can show a link to create one.
+        // @see \Drupal\Core\Entity\Controller\EntityController::addPage()
+        $bundle_access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type->getBundleEntityType());
+        $access = $access->orIf($bundle_access_control_handler->createAccess(NULL, $account, [], TRUE));
+        if ($access->isAllowed()) {
+          return $access;
+        }
       }
     }
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php
index e15fe848bf009dd0b1901eed7f3d1c065ee821ab..5550ede34a7d02e285d55f26da45bf320fd96db1 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/MapItem.php
@@ -64,7 +64,12 @@ public function setValue($values, $notify = TRUE) {
         $values = $values->getValue();
       }
       else {
-        $values = unserialize($values);
+        if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
+          $values = unserialize($values, ['allowed_classes' => FALSE]);
+        }
+        else {
+          $values = unserialize($values);
+        }
       }
     }
 
diff --git a/core/modules/hal/src/Normalizer/FieldItemNormalizer.php b/core/modules/hal/src/Normalizer/FieldItemNormalizer.php
index 349c4fd5e70307e3e0df807ff9e324aba0a7ef7a..de7ff4b771b7676db3de8095e50935d8a70fdd9b 100644
--- a/core/modules/hal/src/Normalizer/FieldItemNormalizer.php
+++ b/core/modules/hal/src/Normalizer/FieldItemNormalizer.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Field\FieldItemInterface;
 use Drupal\Core\TypedData\TypedDataInternalPropertiesHelper;
 use Drupal\serialization\Normalizer\FieldableEntityNormalizerTrait;
+use Drupal\serialization\Normalizer\SerializedColumnNormalizerTrait;
 use Symfony\Component\Serializer\Exception\InvalidArgumentException;
 
 /**
@@ -13,6 +14,7 @@
 class FieldItemNormalizer extends NormalizerBase {
 
   use FieldableEntityNormalizerTrait;
+  use SerializedColumnNormalizerTrait;
 
   /**
    * {@inheritdoc}
@@ -45,6 +47,7 @@ public function denormalize($data, $class, $format = NULL, array $context = [])
     }
 
     $field_item = $context['target_instance'];
+    $this->checkForSerializedStrings($data, $class, $field_item);
 
     // If this field is translatable, we need to create a translated instance.
     if (isset($data['lang'])) {
diff --git a/core/modules/hal/tests/src/Kernel/DenormalizeTest.php b/core/modules/hal/tests/src/Kernel/DenormalizeTest.php
index 87eb97329f003a3044e875ac4c528b7183330266..fde694fa690f362bdc8416d4ab76446d2c559946 100644
--- a/core/modules/hal/tests/src/Kernel/DenormalizeTest.php
+++ b/core/modules/hal/tests/src/Kernel/DenormalizeTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\hal\Kernel;
 
 use Drupal\Core\Url;
+use Drupal\entity_test\Entity\EntitySerializedField;
 use Drupal\field\Entity\FieldConfig;
 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
 
diff --git a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
index 8fa765e0b6cb551f2b6719b781885f90ae4f94d8..431512c290cb08b9e2b0316ac026e92dd32c3a8c 100644
--- a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
+++ b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
@@ -191,7 +191,12 @@ public function setValue($values, $notify = TRUE) {
     //   SqlContentEntityStorage::loadFieldItems, see
     //   https://www.drupal.org/node/2414835
     if (is_string($values['options'])) {
-      $values['options'] = unserialize($values['options']);
+      if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
+        $values['options'] = unserialize($values['options'], ['allowed_classes' => FALSE]);
+      }
+      else {
+        $values['options'] = unserialize($values['options']);
+      }
     }
     parent::setValue($values, $notify);
   }
diff --git a/core/modules/media/tests/src/Functional/Rest/MediaResourceTestBase.php b/core/modules/media/tests/src/Functional/Rest/MediaResourceTestBase.php
index 264d610604d69756c118e57ba55b5c81390045c2..a69748ff38458d85ffd719232fb04bd39d4b334f 100644
--- a/core/modules/media/tests/src/Functional/Rest/MediaResourceTestBase.php
+++ b/core/modules/media/tests/src/Functional/Rest/MediaResourceTestBase.php
@@ -359,7 +359,7 @@ protected function uploadFile() {
 
     // To still run the complete test coverage for POSTing a Media entity, we
     // must revoke the additional permissions that we granted.
-    $role = Role::load(static::$auth ? RoleInterface::AUTHENTICATED_ID : RoleInterface::AUTHENTICATED_ID);
+    $role = Role::load(static::$auth ? RoleInterface::AUTHENTICATED_ID : RoleInterface::ANONYMOUS_ID);
     $role->revokePermission('create camelids media');
     $role->trustData()->save();
   }
diff --git a/core/modules/node/src/NodeAccessControlHandler.php b/core/modules/node/src/NodeAccessControlHandler.php
index 5ccc6425e36daf45dab23af61fe64dc14536b826..7fd27dea0403a7bb14649d64badb9d5ef2fc186a 100644
--- a/core/modules/node/src/NodeAccessControlHandler.php
+++ b/core/modules/node/src/NodeAccessControlHandler.php
@@ -80,7 +80,7 @@ public function createAccess($entity_bundle = NULL, AccountInterface $account =
       return $return_as_object ? $result : $result->isAllowed();
     }
     if (!$account->hasPermission('access content')) {
-      $result = AccessResult::forbidden()->cachePerPermissions();
+      $result = AccessResult::forbidden("The 'access content' permission is required.")->cachePerPermissions();
       return $return_as_object ? $result : $result->isAllowed();
     }
 
diff --git a/core/modules/node/tests/src/Functional/Rest/NodeResourceTestBase.php b/core/modules/node/tests/src/Functional/Rest/NodeResourceTestBase.php
index 9f9a114924fde51a8a0c68c54fbff6dadabe0a0f..ebf967ed64d725f250c35c6d7ffdf9124c48b82d 100644
--- a/core/modules/node/tests/src/Functional/Rest/NodeResourceTestBase.php
+++ b/core/modules/node/tests/src/Functional/Rest/NodeResourceTestBase.php
@@ -210,7 +210,7 @@ protected function getExpectedUnauthorizedAccessMessage($method) {
       return parent::getExpectedUnauthorizedAccessMessage($method);
     }
 
-    if ($method === 'GET' || $method == 'PATCH' || $method == 'DELETE') {
+    if ($method === 'GET' || $method == 'PATCH' || $method == 'DELETE' || $method == 'POST') {
       return "The 'access content' permission is required.";
     }
     return parent::getExpectedUnauthorizedAccessMessage($method);
diff --git a/core/modules/rest/rest.post_update.php b/core/modules/rest/rest.post_update.php
index 8ed5a6dbff124f821c031a24e2ca98c7800da0ab..e1e1d20301f6380f3ffeffce337d206fc6306d63 100644
--- a/core/modules/rest/rest.post_update.php
+++ b/core/modules/rest/rest.post_update.php
@@ -61,3 +61,10 @@ function rest_post_update_resource_granularity() {
     }
   }
 }
+
+/**
+ * Clear caches due to changes in route definitions.
+ */
+function rest_post_update_161923() {
+  // Empty post-update hook.
+}
diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
index a56de490abfaa886aa17ce2594efa05592408727..988b6415a6434fdd13f343205b0b0907ce05fe25 100644
--- a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
+++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
@@ -377,6 +377,10 @@ protected function getBaseRoute($canonical_path, $method) {
       case 'GET':
         $route->setRequirement('_entity_access', $this->entityType->id() . '.view');
         break;
+      case 'POST':
+        $route->setRequirement('_entity_create_any_access', $this->entityType->id());
+        $route->setOption('_ignore_create_bundle_access', TRUE);
+        break;
       case 'PATCH':
         $route->setRequirement('_entity_access', $this->entityType->id() . '.update');
         break;
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
index 7b6011ee06762a6a03c6ed08125668af87e6a3c6..1bc41be84e3d42d58d98b3a156b2963011433076 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
@@ -872,18 +872,6 @@ public function testPost() {
 
     $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType;
 
-    // DX: 400 when no request body.
-    $response = $this->request('POST', $url, $request_options);
-    $this->assertResourceErrorResponse(400, 'No entity content received.', $response);
-
-    $request_options[RequestOptions::BODY] = $unparseable_request_body;
-
-    // DX: 400 when unparseable request body.
-    $response = $this->request('POST', $url, $request_options);
-    $this->assertResourceErrorResponse(400, 'Syntax error', $response);
-
-    $request_options[RequestOptions::BODY] = $parseable_invalid_request_body;
-
     if (static::$auth) {
       // DX: forgetting authentication: authentication provider-specific error
       // response.
@@ -895,16 +883,22 @@ public function testPost() {
 
     // DX: 403 when unauthorized.
     $response = $this->request('POST', $url, $request_options);
-    // @todo Remove this if-test in https://www.drupal.org/project/drupal/issues/2820364
-    if (static::$entityTypeId === 'media' && !static::$auth) {
-      $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nname: Name: this field cannot hold more than 1 values.\nfield_media_file.0: You do not have access to the referenced entity (file: 3).\n", $response);
-    }
-    else {
-      $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('POST'), $response);
-    }
+    $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('POST'), $response);
 
     $this->setUpAuthorization('POST');
 
+    // DX: 400 when no request body.
+    $response = $this->request('POST', $url, $request_options);
+    $this->assertResourceErrorResponse(400, 'No entity content received.', $response);
+
+    $request_options[RequestOptions::BODY] = $unparseable_request_body;
+
+    // DX: 400 when unparseable request body.
+    $response = $this->request('POST', $url, $request_options);
+    $this->assertResourceErrorResponse(400, 'Syntax error', $response);
+
+    $request_options[RequestOptions::BODY] = $parseable_invalid_request_body;
+
     // DX: 422 when invalid entity: multiple values sent for single-value field.
     $response = $this->request('POST', $url, $request_options);
     $label_field = $this->entity->getEntityType()->hasKey('label') ? $this->entity->getEntityType()->getKey('label') : static::$labelFieldName;
diff --git a/core/modules/serialization/src/Normalizer/FieldItemNormalizer.php b/core/modules/serialization/src/Normalizer/FieldItemNormalizer.php
index a463956b6242cb7c8f7aa821185ee1e8b99ac9ed..2af0afc86ab03111c444ef8453f77dbde567bc7e 100644
--- a/core/modules/serialization/src/Normalizer/FieldItemNormalizer.php
+++ b/core/modules/serialization/src/Normalizer/FieldItemNormalizer.php
@@ -12,6 +12,7 @@
 class FieldItemNormalizer extends ComplexDataNormalizer implements DenormalizerInterface {
 
   use FieldableEntityNormalizerTrait;
+  use SerializedColumnNormalizerTrait;
 
   /**
    * {@inheritdoc}
@@ -32,6 +33,7 @@ public function denormalize($data, $class, $format = NULL, array $context = [])
 
     /** @var \Drupal\Core\Field\FieldItemInterface $field_item */
     $field_item = $context['target_instance'];
+    $this->checkForSerializedStrings($data, $class, $field_item);
 
     $field_item->setValue($this->constructValue($data, $context));
     return $field_item;
diff --git a/core/modules/serialization/src/Normalizer/FieldableEntityNormalizerTrait.php b/core/modules/serialization/src/Normalizer/FieldableEntityNormalizerTrait.php
index 3eff65a9be1e5f4374091ecf5d54c57bf3a861b3..0240da8f3b9b5476f272c9fa7aff3a01fa6f139b 100644
--- a/core/modules/serialization/src/Normalizer/FieldableEntityNormalizerTrait.php
+++ b/core/modules/serialization/src/Normalizer/FieldableEntityNormalizerTrait.php
@@ -223,15 +223,24 @@ protected function constructValue($data, $context) {
     assert($item_definition instanceof FieldItemDataDefinitionInterface);
     $property_definitions = $item_definition->getPropertyDefinitions();
 
-    if (!is_array($data)) {
-      $property_value = $data;
-      $property_value_class = $property_definitions[$item_definition->getMainPropertyName()]->getClass();
+    $serialized_property_names = $this->getCustomSerializedPropertyNames($field_item);
+    $denormalize_property = function ($property_name, $property_value, $property_value_class, $context) use ($serialized_property_names) {
       if ($this->serializer->supportsDenormalization($property_value, $property_value_class, NULL, $context)) {
         return $this->serializer->denormalize($property_value, $property_value_class, NULL, $context);
       }
       else {
+        if (in_array($property_name, $serialized_property_names, TRUE)) {
+          $property_value = serialize($property_value);
+        }
         return $property_value;
       }
+    };
+
+    if (!is_array($data)) {
+      $property_value = $data;
+      $property_name = $item_definition->getMainPropertyName();
+      $property_value_class = $property_definitions[$property_name]->getClass();
+      return $denormalize_property($property_name, $property_value, $property_value_class, $context);
     }
 
     $data_internal = [];
@@ -243,12 +252,7 @@ protected function constructValue($data, $context) {
         }
         $property_value = $data[$property_name];
         $property_value_class = $property_definition->getClass();
-        if ($this->serializer->supportsDenormalization($property_value, $property_value_class, NULL, $context)) {
-          $data_internal[$property_name] = $this->serializer->denormalize($property_value, $property_value_class, NULL, $context);
-        }
-        else {
-          $data_internal[$property_name] = $property_value;
-        }
+        $data_internal[$property_name] = $denormalize_property($property_name, $property_value, $property_value_class, $context);
       }
     }
     else {
diff --git a/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php b/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php
index 7294d6f051a0ce9fcc7e14fba28ea0e03a71cabf..a594757e7dca7e4bc94b18e9db09e7785ca41e14 100644
--- a/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php
+++ b/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\serialization\Normalizer;
 
+use Drupal\Core\Field\FieldItemInterface;
 use Drupal\Core\TypedData\PrimitiveInterface;
 
 /**
@@ -9,6 +10,8 @@
  */
 class PrimitiveDataNormalizer extends NormalizerBase {
 
+  use SerializedColumnNormalizerTrait;
+
   /**
    * {@inheritdoc}
    */
@@ -18,6 +21,14 @@ class PrimitiveDataNormalizer extends NormalizerBase {
    * {@inheritdoc}
    */
   public function normalize($object, $format = NULL, array $context = []) {
+    $parent = $object->getParent();
+    if ($parent instanceof FieldItemInterface && $object->getValue()) {
+      $serialized_property_names = $this->getCustomSerializedPropertyNames($parent);
+      if (in_array($object->getName(), $serialized_property_names, TRUE)) {
+        return unserialize($object->getValue());
+      }
+    }
+
     // Typed data casts NULL objects to their empty variants, so for example
     // the empty string ('') for string type data, or 0 for integer typed data.
     // In a better world with typed data implementing algebraic data types,
diff --git a/core/modules/serialization/src/Normalizer/SerializedColumnNormalizerTrait.php b/core/modules/serialization/src/Normalizer/SerializedColumnNormalizerTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..bf6eb0643cd51fd474afbd1a8837f88bd6812a98
--- /dev/null
+++ b/core/modules/serialization/src/Normalizer/SerializedColumnNormalizerTrait.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace Drupal\serialization\Normalizer;
+
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Field\FieldItemInterface;
+
+/**
+ * A trait providing methods for serialized columns.
+ */
+trait SerializedColumnNormalizerTrait {
+
+  /**
+   * Checks if there is a serialized string for a column.
+   *
+   * @param mixed $data
+   *   The field item data to denormalize.
+   * @param string $class
+   *   The expected class to instantiate.
+   * @param \Drupal\Core\Field\FieldItemInterface $field_item
+   *   The field item.
+   */
+  protected function checkForSerializedStrings($data, $class, FieldItemInterface $field_item) {
+    // Require specialized denormalizers for fields with 'serialize' columns.
+    // Note: this cannot be checked in ::supportsDenormalization() because at
+    //       that time we only have the field item class. ::hasSerializeColumn()
+    //       must be able to call $field_item->schema(), which requires a field
+    //       storage definition. To determine that, the entity type and bundle
+    //       must be known, which is contextual information that the Symfony
+    //       serializer does not pass to ::supportsDenormalization().
+    if (!is_array($data)) {
+      $data = [$field_item->getDataDefinition()->getMainPropertyName() => $data];
+    }
+    if ($this->dataHasStringForSerializeColumn($field_item, $data)) {
+      $field_name = $field_item->getParent() ? $field_item->getParent()->getName() : $field_item->getName();
+      throw new \LogicException(sprintf('The generic FieldItemNormalizer cannot denormalize string values for "%s" properties of the "%s" field (field item class: %s).', implode('", "', $this->getSerializedPropertyNames($field_item)), $field_name, $class));
+    }
+  }
+
+  /**
+   * Checks if the data contains string value for serialize column.
+   *
+   * @param \Drupal\Core\Field\FieldItemInterface $field_item
+   *   The field item.
+   * @param array $data
+   *   The data being denormalized.
+   *
+   * @return bool
+   *   TRUE if there is a string value for serialize column, otherwise FALSE.
+   */
+  protected function dataHasStringForSerializeColumn(FieldItemInterface $field_item, array $data) {
+    foreach ($this->getSerializedPropertyNames($field_item) as $property_name) {
+      if (isset($data[$property_name]) && is_string($data[$property_name])) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+  /**
+   * Gets the names of all serialized properties.
+   *
+   * @param \Drupal\Core\Field\FieldItemInterface $field_item
+   *   The field item.
+   *
+   * @return string[]
+   *   The property names for serialized properties.
+   */
+  protected function getSerializedPropertyNames(FieldItemInterface $field_item) {
+    $field_storage_definition = $field_item->getFieldDefinition()->getFieldStorageDefinition();
+
+    if ($custom_property_names = $this->getCustomSerializedPropertyNames($field_item)) {
+      return $custom_property_names;
+    }
+
+    $field_storage_schema = $field_item->schema($field_storage_definition);
+    // If there are no columns then there are no serialized properties.
+    if (!isset($field_storage_schema['columns'])) {
+      return [];
+    }
+    $serialized_columns = array_filter($field_storage_schema['columns'], function ($column_schema) {
+      return isset($column_schema['serialize']) && $column_schema['serialize'] === TRUE;
+    });
+    return array_keys($serialized_columns);
+  }
+
+  /**
+   * Gets the names of all properties the plugin treats as serialized data.
+   *
+   * This allows the field storage definition or entity type to provide a
+   * setting for serialized properties. This can be used for fields that
+   * handle serialized data themselves and do not rely on the serialized schema
+   * flag.
+   *
+   * @param \Drupal\Core\Field\FieldItemInterface $field_item
+   *   The field item.
+   *
+   * @return string[]
+   *   The property names for serialized properties.
+   */
+  protected function getCustomSerializedPropertyNames(FieldItemInterface $field_item) {
+    if ($field_item instanceof PluginInspectionInterface) {
+      $definition = $field_item->getPluginDefinition();
+      $serialized_fields = $field_item->getEntity()->getEntityType()->get('serialized_field_property_names');
+      $field_name = $field_item->getFieldDefinition()->getName();
+      if (is_array($serialized_fields) && isset($serialized_fields[$field_name]) && is_array($serialized_fields[$field_name])) {
+        return $serialized_fields[$field_name];
+      }
+      if (isset($definition['serialized_property_names']) && is_array($definition['serialized_property_names'])) {
+        return $definition['serialized_property_names'];
+      }
+    }
+    return [];
+  }
+
+}
diff --git a/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php b/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php
index c95a9d96e60f6a7af84a15a45e91ef5eadf9eaf0..e9dcf5c50483d5fa4d6075c5b15b7a62606e1eaa 100644
--- a/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php
+++ b/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Render\FormattableMarkup;
+use Drupal\entity_test\Entity\EntitySerializedField;
 use Drupal\entity_test\Entity\EntityTestMulRev;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php
index 67bd3b6625579f8170dfb1addd6666ee9f4f6ab6..a783d0928c630a0b37209f73f20c4a48ded7d6c9 100644
--- a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php
+++ b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\serialization\Unit\Normalizer;
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
 use Drupal\Core\GeneratedUrl;
@@ -435,6 +436,33 @@ protected function assertDenormalize(array $data) {
         ->shouldBeCalled();
     }
 
+    // Avoid a static method call by returning dummy property data.
+    $this->fieldDefinition
+      ->getFieldStorageDefinition()
+      ->willReturn()
+      ->shouldBeCalled();
+    $this->fieldDefinition
+      ->getName()
+      ->willReturn('field_reference')
+      ->shouldBeCalled();
+    $entity = $this->prophesize(EntityInterface::class);
+    $entity_type = $this->prophesize(EntityTypeInterface::class);
+    $entity->getEntityType()
+      ->willReturn($entity_type->reveal())
+      ->shouldBeCalled();
+    $this->fieldItem
+      ->getPluginDefinition()
+      ->willReturn([
+        'serialized_property_names' => [
+          'foo' => 'bar',
+        ],
+      ])
+      ->shouldBeCalled();
+    $this->fieldItem
+      ->getEntity()
+      ->willReturn($entity->reveal())
+      ->shouldBeCalled();
+
     $context = ['target_instance' => $this->fieldItem->reveal()];
     $denormalized = $this->normalizer->denormalize($data, EntityReferenceItem::class, 'json', $context);
     $this->assertSame($context['target_instance'], $denormalized);
diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php
index 4d0127926e1da8b022e0b15079cc7acf31ba19f1..af19ba339dc875cea0447ffb3759e321b5985ca0 100644
--- a/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php
+++ b/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\Tests\serialization\Unit\Normalizer;
 
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\Plugin\Field\FieldType\CreatedItem;
 use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
 use Drupal\Core\Field\Plugin\Field\FieldType\TimestampItem;
@@ -120,6 +123,29 @@ public function testDenormalize() {
     $timestamp_item->setValue(['value' => $timestamp_data_denormalization])
       ->shouldBeCalled();
 
+    // Avoid a static method call by returning dummy property data.
+    $field_definition = $this->prophesize(FieldDefinitionInterface::class);
+    $timestamp_item
+      ->getFieldDefinition()
+      ->willReturn($field_definition->reveal())
+      ->shouldBeCalled();
+    $timestamp_item->getPluginDefinition()
+      ->willReturn([
+        'serialized_property_names' => [
+          'foo' => 'bar',
+        ],
+      ])
+      ->shouldBeCalled();
+    $entity = $this->prophesize(EntityInterface::class);
+    $entity_type = $this->prophesize(EntityTypeInterface::class);
+    $entity->getEntityType()
+      ->willReturn($entity_type->reveal())
+      ->shouldBeCalled();
+    $timestamp_item
+      ->getEntity()
+      ->willReturn($entity->reveal())
+      ->shouldBeCalled();
+
     $context = [
       'target_instance' => $timestamp_item->reveal(),
       'datetime_allowed_formats' => [\DateTime::RFC3339],