diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
index 29b8a9aa95..aeb36b5b25 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -1211,8 +1211,18 @@ protected function loadFromDedicatedTables(array &$values, $load_from_revision)
             // prefixed database column.
             foreach ($storage_definition->getColumns() as $column => $attributes) {
               $column_name = $table_mapping->getFieldColumnName($storage_definition, $column);
-              // Unserialize the value if specified in the column schema.
-              $item[$column] = (!empty($attributes['serialize'])) ? unserialize($row->$column_name) : $row->$column_name;
+              // If there is no main property and only a single column that is
+              // serialized, put the values directly into the $item without the
+              // column.
+              // @todo Give field types more control over this behavior in
+              //   https://www.drupal.org/node/2232427.
+              if (!$storage_definition->getMainPropertyName() && count($storage_definition->getColumns()) == 1 && !empty($attributes['serialize'])) {
+                $item = unserialize($row->$column_name);
+              }
+              else {
+                // Unserialize the value if specified in the column schema.
+                $item[$column] = (!empty($attributes['serialize'])) ? unserialize($row->$column_name) : $row->$column_name;
+              }
             }
 
             // Add the item to the field values for the entity.
@@ -1315,10 +1325,19 @@ protected function saveToDedicatedTables(ContentEntityInterface $entity, $update
           ];
           foreach ($storage_definition->getColumns() as $column => $attributes) {
             $column_name = $table_mapping->getFieldColumnName($storage_definition, $column);
-            // Serialize the value if specified in the column schema.
-            $value = $item->$column;
-            if (!empty($attributes['serialize'])) {
-              $value = serialize($value);
+            // If there is no main property and only a single column that is
+            // serialized, serialize all the values from the field item.
+            // @todo Give field types more control over this behavior in
+            //   https://www.drupal.org/node/2232427.
+            if (!$storage_definition->getMainPropertyName() && count($storage_definition->getColumns()) == 1 && !empty($attributes['serialize'])) {
+              $value = serialize($item->getValue());
+            }
+            else {
+              $value = $item->$column;
+              // Serialize the value if specified in the column schema.
+              if (!empty($attributes['serialize'])) {
+                $value = serialize($value);
+              }
             }
             $record[$column_name] = drupal_schema_get_field_value($attributes, $value);
           }
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
index 3349ebd30d..fb898c58a1 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -2083,7 +2083,9 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor
       // A dedicated table only contain rows for actual field values, and no
       // rows for entities where the field is empty. Thus, we can safely
       // enforce 'not null' on the columns for the field's required properties.
-      $data_schema['fields'][$real_name]['not null'] = $properties[$column_name]->isRequired();
+      if (isset($properties[$column_name])) {
+        $data_schema['fields'][$real_name]['not null'] = $properties[$column_name]->isRequired();
+      }
     }
 
     // Add indexes.
diff --git a/core/modules/field/tests/src/Kernel/MapItemTest.php b/core/modules/field/tests/src/Kernel/MapItemTest.php
new file mode 100644
index 0000000000..af35fa0bef
--- /dev/null
+++ b/core/modules/field/tests/src/Kernel/MapItemTest.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace Drupal\Tests\field\Kernel;
+
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+
+/**
+ * Tests the map field type.
+ *
+ * @group field
+ */
+class MapItemTest extends FieldKernelTestBase {
+
+  /**
+   * The name of the field to use in this test.
+   *
+   * @var string
+   */
+  protected $fieldName = 'field_test';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Create a 'test_field' field and storage for validation.
+    FieldStorageConfig::create([
+      'field_name' => $this->fieldName,
+      'entity_type' => 'entity_test',
+      'type' => 'map',
+    ])->save();
+    FieldConfig::create([
+      'entity_type' => 'entity_test',
+      'field_name' => $this->fieldName,
+      'bundle' => 'entity_test',
+    ])->save();
+  }
+
+  /**
+   * Tests using entity fields of the map field type.
+   */
+  public function testTestItem() {
+    // Verify entity creation.
+    $entity = EntityTest::create();
+    $entity->field_test->test1 = 'value1';
+    $entity->field_test->test2 = 'value2';
+    $entity->field_test->test_array = ['nested' => 'structure'];
+
+    $entity->name->value = $this->randomMachineName();
+    $entity->save();
+
+    // Verify entity has been created properly.
+    $id = $entity->id();
+    $entity = EntityTest::load($id);
+    $this->assertEquals('value1', $entity->field_test->test1);
+    $this->assertEquals('value2', $entity->field_test->test2);
+    $this->assertEquals(['nested' => 'structure'], $entity->field_test->test_array);
+
+    // Verify changing the field value.
+    $entity->field_test->test1 = 'new_value';
+    $this->assertEquals('new_value', $entity->field_test->test1);
+
+    // Read changed entity and assert changed values.
+    $entity->save();
+    $entity = EntityTest::load($id);
+    $this->assertEquals('new_value', $entity->field_test->test1);
+  }
+
+}
