diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
index d3087b7..a85e313 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -1407,10 +1407,11 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st
       // table. For this reason the revision ID field cannot be marked as NOT
       // NULL.
       unset($keys['label'], $keys['revision']);
-      // Key fields may not be NULL.
-      if (in_array($field_name, $keys)) {
-        $schema['fields'][$schema_field_name]['not null'] = TRUE;
-      }
+      // In order to optimize indexes, forbid NULL values in Key fields. Other
+      // columns necessarily allow NULL values in order to support adding a
+      // base field definition to an entity type with non-empty base tables.
+      // @todo Revisit in https://www.drupal.org/node/2346019.
+      $schema['fields'][$schema_field_name]['not null'] = in_array($field_name, $keys);
     }
 
     if (!empty($field_schema['indexes'])) {
@@ -1600,6 +1601,7 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor
 
     // Check that the schema does not include forbidden column names.
     $schema = $storage_definition->getSchema();
+    $properties = $storage_definition->getPropertyDefinitions();
     $table_mapping = $this->storage->getTableMapping();
     if (array_intersect(array_keys($schema['columns']), $table_mapping->getReservedColumns())) {
       throw new FieldException(format_string('Illegal field column names on @field_name', array('@field_name' => $storage_definition->getName())));
@@ -1609,6 +1611,10 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor
     foreach ($schema['columns'] as $column_name => $attributes) {
       $real_name = $table_mapping->getFieldColumnName($storage_definition, $column_name);
       $data_schema['fields'][$real_name] = $attributes;
+      // Properties marked as 'required' do not allow NULL values, others do.
+      // Note: this works because dedicated tables contain no row for empty
+      // fields.
+      $data_schema['fields'][$real_name]['not null'] = $properties[$column_name]->isRequired();
     }
 
     // Add indexes.
diff --git a/core/lib/Drupal/Core/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Field/FieldItemInterface.php
index 862b9e5..0613c9f 100644
--- a/core/lib/Drupal/Core/Field/FieldItemInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldItemInterface.php
@@ -28,6 +28,9 @@
   /**
    * Defines field item properties.
    *
+   * Properties that are required to constitue a valid, non-empty item should
+   * be denoted with \Drupal\Core\TypedData\DataDefinition::setRequired().
+   *
    * @return \Drupal\Core\TypedData\DataDefinitionInterface[]
    *   An array of property definitions of contained properties, keyed by
    *   property name.
@@ -67,10 +70,12 @@ public static function mainPropertyName();
    *   following key/value pairs:
    *   - columns: An array of Schema API column specifications, keyed by column
    *     name. The columns need to be a subset of the properties defined in
-   *     propertyDefinitions(). It is recommended to avoid having the column
-   *     definitions depend on field settings when possible. No assumptions
-   *     should be made on how storage engines internally use the original
-   *     column name to structure their storage.
+   *     propertyDefinitions(). The 'not null' property is ignored if present,
+   *     as it is determined automatically by the storage controller depending
+   *     on the table layout and the property definitions. It is recommended to
+   *     avoid having the column definitions depend on field settings when
+   *     possible. No assumptions should be made on how storage engines
+   *     internally use the original column name to structure their storage.
    *   - unique keys: (optional) An array of Schema API unique key definitions.
    *     Only columns that appear in the 'columns' array are allowed.
    *   - indexes: (optional) An array of Schema API index definitions. Only
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php
index 2fb8242..1baf7bd 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php
@@ -43,7 +43,8 @@ public static function defaultStorageSettings() {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('boolean')
-      ->setLabel(t('Boolean value'));
+      ->setLabel(t('Boolean value'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
@@ -57,7 +58,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'int',
           'size' => 'tiny',
-          'not null' => TRUE,
         ),
       ),
     );
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php
index 1e241f9..b46cfc7 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php
@@ -41,7 +41,8 @@ public static function defaultStorageSettings() {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('string')
-      ->setLabel(t('Decimal value'));
+      ->setLabel(t('Decimal value'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
@@ -56,7 +57,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
           'type' => 'numeric',
           'precision' => $field_definition->getSetting('precision'),
           'scale' => $field_definition->getSetting('scale'),
-          'not null' => FALSE
         )
       ),
     );
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php
index 38c434a..ad13c37 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php
@@ -32,7 +32,8 @@ class EmailItem extends FieldItemBase {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('email')
-      ->setLabel(t('E-mail'));
+      ->setLabel(t('E-mail'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
@@ -46,7 +47,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'varchar',
           'length' => Email::EMAIL_MAX_LENGTH,
-          'not null' => FALSE,
         ),
       ),
     );
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
index a6c6bed..e0cae3c 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -74,7 +74,10 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
       $target_id_definition = DataDefinition::create('string')
         ->setLabel(t('@label ID', array($target_type_info->getLabel())));
     }
+    // FIXME
+    // $target_id_definition->setRequired(TRUE);
     $properties['target_id'] = $target_id_definition;
+
     $properties['entity'] = DataReferenceDefinition::create('entity')
       ->setLabel($target_type_info->getLabel())
       ->setDescription(t('The referenced entity'))
@@ -110,7 +113,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
           'description' => 'The ID of the target entity.',
           'type' => 'int',
           'unsigned' => TRUE,
-          'not null' => TRUE,
         ),
       );
     }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
index 038d4e1..695e40b 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
@@ -29,7 +29,8 @@ class FloatItem extends NumericItemBase {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('float')
-      ->setLabel(t('Float'));
+      ->setLabel(t('Float'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
@@ -42,7 +43,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
       'columns' => array(
         'value' => array(
           'type' => 'float',
-          'not null' => FALSE,
         ),
       ),
     );
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
index a2f569b..b1c9fa1 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
@@ -53,7 +53,8 @@ public static function defaultFieldSettings() {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('integer')
-      ->setLabel(t('Integer value'));
+      ->setLabel(t('Integer value'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
@@ -92,7 +93,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
       'columns' => array(
         'value' => array(
           'type' => 'int',
-          'not null' => FALSE,
           // Expose the 'unsigned' setting in the field item schema.
           'unsigned' => $field_definition->getSetting('unsigned'),
           // Expose the 'size' setting in the field item schema. For instance,
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
index 961eb67..80e0191 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
@@ -35,7 +35,8 @@ class LanguageItem extends FieldItemBase {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('string')
-      ->setLabel(t('Language code'));
+      ->setLabel(t('Language code'))
+      ->setRequired(TRUE);
 
     $properties['language'] = DataReferenceDefinition::create('language')
       ->setLabel(t('Language object'))
@@ -56,7 +57,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'varchar',
           'length' => 12,
-          'not null' => FALSE,
         ),
       ),
     );
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
index 3f641e5..11f56f2 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
@@ -43,7 +43,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'varchar',
           'length' => (int) $field_definition->getSetting('max_length'),
-          'not null' => FALSE,
         ),
       ),
     );
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItemBase.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItemBase.php
index c1ff41b..c763466 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItemBase.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItemBase.php
@@ -24,7 +24,8 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
     // This is called very early by the user entity roles field. Prevent
     // early t() calls by using the TranslationWrapper.
     $properties['value'] = DataDefinition::create('string')
-      ->setLabel(new TranslationWrapper('Text value'));
+      ->setLabel(new TranslationWrapper('Text value'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php
index d355287..2dafed5 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php
@@ -40,7 +40,8 @@ class TimestampItem extends FieldItemBase {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('timestamp')
-      ->setLabel(t('Timestamp value'));
+      ->setLabel(t('Timestamp value'))
+      ->setRequired(TRUE);
     return $properties;
   }
 
@@ -52,7 +53,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
       'columns' => array(
         'value' => array(
           'type' => 'int',
-          'not null' => FALSE,
         ),
       ),
     );
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
index a50696b..ec54d22 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
@@ -41,7 +41,8 @@ public static function defaultStorageSettings() {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('uri')
-      ->setLabel(t('URI value'));
+      ->setLabel(t('URI value'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
@@ -55,7 +56,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'varchar',
           'length' => (int) $field_definition->getSetting('max_length'),
-          'not null' => TRUE,
         ),
       ),
     );
diff --git a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php
index 93274a5..24293f9 100644
--- a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php
+++ b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php
@@ -55,7 +55,8 @@ public static function defaultFieldSettings() {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['status'] = DataDefinition::create('integer')
-      ->setLabel(t('Comment status'));
+      ->setLabel(t('Comment status'))
+      ->setRequired(TRUE);
 
     $properties['cid'] = DataDefinition::create('integer')
       ->setLabel(t('Last comment ID'));
@@ -87,7 +88,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'status' => array(
           'description' => 'Whether comments are allowed on this entity: 0 = no, 1 = closed (read only), 2 = open (read/write).',
           'type' => 'int',
-          'not null' => TRUE,
           'default' => 0,
         ),
       ),
diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php
index f63ffd6..ac8b7bc 100644
--- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php
+++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php
@@ -51,7 +51,8 @@ public static function defaultStorageSettings() {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('datetime_iso8601')
-      ->setLabel(t('Date value'));
+      ->setLabel(t('Date value'))
+      ->setRequired(TRUE);
 
     $properties['date'] = DataDefinition::create('any')
       ->setLabel(t('Computed date'))
@@ -73,7 +74,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
           'description' => 'The date value.',
           'type' => 'varchar',
           'length' => 20,
-          'not null' => FALSE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/field/src/Tests/TestItemTest.php b/core/modules/field/src/Tests/TestItemTest.php
index 6b41870..b282fd1 100644
--- a/core/modules/field/src/Tests/TestItemTest.php
+++ b/core/modules/field/src/Tests/TestItemTest.php
@@ -83,7 +83,6 @@ public function testTestItem() {
         'value' => array(
           'type' => 'int',
           'size' => 'medium',
-          'not null' => FALSE,
         ),
       ),
       'unique keys' => array(),
diff --git a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/HiddenTestItem.php b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/HiddenTestItem.php
index b145abe..bbac229 100644
--- a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/HiddenTestItem.php
+++ b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/HiddenTestItem.php
@@ -24,14 +24,4 @@
  */
 class HiddenTestItem extends TestItem {
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
-    $properties['value'] = DataDefinition::create('integer')
-      ->setLabel(t('Test integer value'));
-
-    return $properties;
-  }
-
 }
diff --git a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestItem.php b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestItem.php
index 456f911..ddfe207 100644
--- a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestItem.php
+++ b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestItem.php
@@ -50,7 +50,8 @@ public static function defaultFieldSettings() {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('integer')
-      ->setLabel(t('Test integer value'));
+      ->setLabel(t('Test integer value'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
@@ -64,7 +65,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'int',
           'size' => 'medium',
-          'not null' => FALSE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php
index b21a182..7cf26d3 100644
--- a/core/modules/file/src/Entity/File.php
+++ b/core/modules/file/src/Entity/File.php
@@ -274,7 +274,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
 
     $fields['status'] = BaseFieldDefinition::create('boolean')
       ->setLabel(t('Status'))
-      ->setDescription(t('The status of the file, temporary (FALSE) and permanent (TRUE).'));
+      ->setDescription(t('The status of the file, temporary (FALSE) and permanent (TRUE).'))
+      ->setDefaultValue(FALSE);
 
     $fields['created'] = BaseFieldDefinition::create('created')
       ->setLabel(t('Created'))
diff --git a/core/modules/file/src/Plugin/Field/FieldType/FileItem.php b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php
index 1c00e76..48c94ed 100644
--- a/core/modules/file/src/Plugin/Field/FieldType/FileItem.php
+++ b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php
@@ -64,7 +64,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'target_id' => array(
           'description' => 'The ID of the file entity.',
           'type' => 'int',
-          'not null' => TRUE,
           'unsigned' => TRUE,
         ),
         'display' => array(
@@ -72,13 +71,11 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
           'type' => 'int',
           'size' => 'tiny',
           'unsigned' => TRUE,
-          'not null' => TRUE,
           'default' => 1,
         ),
         'description' => array(
           'description' => 'A description of the file.',
           'type' => 'text',
-          'not null' => FALSE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php b/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php
index 6d1c149..d5f4269 100644
--- a/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php
+++ b/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php
@@ -96,20 +96,17 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'target_id' => array(
           'description' => 'The ID of the file entity.',
           'type' => 'int',
-          'not null' => TRUE,
           'unsigned' => TRUE,
         ),
         'alt' => array(
           'description' => "Alternative image text, for the image's 'alt' attribute.",
           'type' => 'varchar',
           'length' => 512,
-          'not null' => FALSE,
         ),
         'title' => array(
           'description' => "Image title text, for the image's 'title' attribute.",
           'type' => 'varchar',
           'length' => 1024,
-          'not null' => FALSE,
         ),
         'width' => array(
           'description' => 'The width of the image in pixels.',
diff --git a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
index 37e40d4..1b347aa 100644
--- a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
+++ b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
@@ -72,32 +72,27 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
           'description' => 'The URL of the link.',
           'type' => 'varchar',
           'length' => 2048,
-          'not null' => FALSE,
         ),
         'title' => array(
           'description' => 'The link text.',
           'type' => 'varchar',
           'length' => 255,
-          'not null' => FALSE,
         ),
         'route_name' => array(
           'description' => 'The machine name of a defined Route this link represents.',
           'type' => 'varchar',
           'length' => 255,
-          'not null' => FALSE,
         ),
         'route_parameters' => array(
           'description' => 'Serialized array of route parameters of the link.',
           'type' => 'blob',
           'size' => 'big',
-          'not null' => FALSE,
           'serialize' => TRUE,
         ),
         'options' => array(
           'description' => 'Serialized array of options for the link.',
           'type' => 'blob',
           'size' => 'big',
-          'not null' => FALSE,
           'serialize' => TRUE,
         ),
       ),
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index 4b7671f..6d618be 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -444,6 +444,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setDescription(t('A boolean indicating whether the node should be displayed at the top of lists in which it appears.'))
       ->setRevisionable(TRUE)
       ->setTranslatable(TRUE)
+      ->setDefaultValue(FALSE)
       ->setDisplayOptions('form', array(
         'type' => 'boolean_checkbox',
         'settings' => array(
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php
index 6fa8fbe..0b6b321 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php
@@ -28,7 +28,8 @@ class ListFloatItem extends ListItemBase {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('float')
-      ->setLabel(t('Float value'));
+      ->setLabel(t('Float value'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php
index 8a0b297..afda838 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php
@@ -28,7 +28,8 @@ class ListIntegerItem extends ListItemBase {
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('integer')
-      ->setLabel(t('Integer value'));
+      ->setLabel(t('Integer value'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
@@ -41,7 +42,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
       'columns' => array(
         'value' => array(
           'type' => 'int',
-          'not null' => FALSE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
index d74049a..a95c8e8 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
@@ -30,7 +30,8 @@ class ListStringItem extends ListItemBase {
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('Text value'))
-      ->addConstraint('Length', array('max' => 255));
+      ->addConstraint('Length', array('max' => 255))
+      ->setRequired(TRUE);
 
     return $properties;
   }
@@ -44,7 +45,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'varchar',
           'length' => 255,
-          'not null' => FALSE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/shortcut/src/ShortcutPathItem.php b/core/modules/shortcut/src/ShortcutPathItem.php
index 8ad82d3..7c63a30 100644
--- a/core/modules/shortcut/src/ShortcutPathItem.php
+++ b/core/modules/shortcut/src/ShortcutPathItem.php
@@ -23,7 +23,8 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
     $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('String value'))
       ->setComputed(TRUE)
-      ->setClass('\Drupal\shortcut\ShortcutPathValue');
+      ->setClass('\Drupal\shortcut\ShortcutPathValue')
+      ->setRequired(TRUE);
     return $properties;
   }
 
diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php b/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
index 83d9780..aeb8074 100644
--- a/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
+++ b/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php
@@ -103,7 +103,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'target_id' => array(
           'type' => 'int',
           'unsigned' => TRUE,
-          'not null' => FALSE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/telephone/src/Plugin/Field/FieldType/TelephoneItem.php b/core/modules/telephone/src/Plugin/Field/FieldType/TelephoneItem.php
index 5e59974..c62db58 100644
--- a/core/modules/telephone/src/Plugin/Field/FieldType/TelephoneItem.php
+++ b/core/modules/telephone/src/Plugin/Field/FieldType/TelephoneItem.php
@@ -34,7 +34,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'varchar',
           'length' => 256,
-          'not null' => FALSE,
         ),
       ),
     );
@@ -45,7 +44,8 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('string')
-      ->setLabel(t('Telephone number'));
+      ->setLabel(t('Telephone number'))
+      ->setRequired(TRUE);
 
     return $properties;
   }
diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextItem.php
index 2585177..dc92859 100644
--- a/core/modules/text/src/Plugin/Field/FieldType/TextItem.php
+++ b/core/modules/text/src/Plugin/Field/FieldType/TextItem.php
@@ -41,12 +41,10 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'varchar',
           'length' => $field_definition->getSetting('max_length'),
-          'not null' => FALSE,
         ),
         'format' => array(
           'type' => 'varchar',
           'length' => 255,
-          'not null' => FALSE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php
index e08f951..2a46cce 100644
--- a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php
+++ b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php
@@ -23,7 +23,8 @@
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('string')
-      ->setLabel(t('Text'));
+      ->setLabel(t('Text'))
+      ->setRequired(TRUE);
 
     $properties['format'] = DataDefinition::create('filter_format')
       ->setLabel(t('Text format'));
diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php
index bf1054f..528d931 100644
--- a/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php
+++ b/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php
@@ -31,12 +31,10 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'text',
           'size' => 'big',
-          'not null' => FALSE,
         ),
         'format' => array(
           'type' => 'varchar',
           'length' => 255,
-          'not null' => FALSE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php
index e0ba0c8..d3aeb6a 100644
--- a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php
+++ b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php
@@ -61,17 +61,14 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'text',
           'size' => 'big',
-          'not null' => FALSE,
         ),
         'summary' => array(
           'type' => 'text',
           'size' => 'big',
-          'not null' => FALSE,
         ),
         'format' => array(
           'type' => 'varchar',
           'length' => 255,
-          'not null' => FALSE,
         ),
       ),
       'indexes' => array(
diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php
index a3a7013..1d3bccb 100644
--- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Entity\ContentEntityType;
 use Drupal\Core\Entity\Sql\DefaultTableMapping;
-use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -1229,6 +1228,19 @@ public function setUpStorageDefinition($field_name, array $schema) {
     $this->storageDefinitions[$field_name]->expects($this->any())
       ->method('getColumns')
       ->will($this->returnValue($schema['columns']));
+    // Add property definitions.
+    if (!empty($schema['columns'])) {
+      $property_definitions = array();
+      foreach ($schema['columns'] as $column => $info) {
+        $property_definitions[$column] = $this->getMock('Drupal\Core\TypedData\DataDefinitionInterface');
+        $property_definitions[$column]->expects($this->any())
+          ->method('isRequired')
+          ->will($this->returnValue(!empty($info['not null'])));
+      }
+      $this->storageDefinitions[$field_name]->expects($this->any())
+        ->method('getPropertyDefinitions')
+        ->will($this->returnValue($property_definitions));
+    }
   }
 
 }
