diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
index 730aaa2..6799b1f 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
@@ -131,7 +131,7 @@ public function loadMultiple(array $ids = NULL) {
       // Remove any invalid ids from the array.
       $passed_ids = array_intersect_key($passed_ids, $entities);
       foreach ($entities as $entity) {
-        $passed_ids[$entity->{$this->idKey}] = $entity;
+        $passed_ids[$entity->id()] = $entity;
       }
       $entities = $passed_ids;
     }
@@ -310,11 +310,6 @@ public function save(EntityInterface $entity) {
       $entity->original = $this->loadUnchanged($id);
     }
 
-    // Build an ID if none is set.
-    if (!isset($entity->{$this->idKey})) {
-      $entity->{$this->idKey} = $entity->id();
-    }
-
     $entity->preSave($this);
     $this->invokeHook('presave', $entity);
 
diff --git a/core/modules/breakpoint/lib/Drupal/breakpoint/Tests/BreakpointAPITest.php b/core/modules/breakpoint/lib/Drupal/breakpoint/Tests/BreakpointAPITest.php
index 85d0711..13b4ef2 100644
--- a/core/modules/breakpoint/lib/Drupal/breakpoint/Tests/BreakpointAPITest.php
+++ b/core/modules/breakpoint/lib/Drupal/breakpoint/Tests/BreakpointAPITest.php
@@ -46,7 +46,7 @@ public function testConfigName() {
     $this->assertTrue($exception, 'breakpoint_config_name: An exception is thrown when an invalid sourceType is entered.');
 
     // Try an invalid source.
-    $breakpoint->id = '';
+    $breakpoint->set('id', '');
     $breakpoint->sourceType = Breakpoint::SOURCE_TYPE_USER_DEFINED;
     $breakpoint->source = 'custom*_module source';
 
@@ -60,7 +60,7 @@ public function testConfigName() {
     $this->assertTrue($exception, 'breakpoint_config_name: An exception is thrown when an invalid source is entered.');
 
     // Try an invalid name (make sure there is at least once capital letter).
-    $breakpoint->id = '';
+    $breakpoint->set('id', '');
     $breakpoint->source = 'custom_module';
     $breakpoint->name = drupal_ucfirst($this->randomName());
 
@@ -74,7 +74,7 @@ public function testConfigName() {
     $this->assertTrue($exception, 'breakpoint_config_name: An exception is thrown when an invalid name is entered.');
 
     // Try a valid breakpoint.
-    $breakpoint->id = '';
+    $breakpoint->set('id', '');
     $breakpoint->name = drupal_strtolower($this->randomName());
     $breakpoint->mediaQuery = 'all';
 
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php
index 19ebaff..17956d7 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php
@@ -39,7 +39,6 @@ function testCRUD() {
     $default_langcode = language_default()->id;
     // Verify default properties on a newly created empty entity.
     $empty = entity_create('config_test');
-    $this->assertIdentical($empty->id, NULL);
     $this->assertTrue($empty->uuid);
     $this->assertIdentical($empty->label, NULL);
     $this->assertIdentical($empty->style, NULL);
@@ -165,7 +164,7 @@ function testCRUD() {
       $this->assertIdentical($config_test->getOriginalId(), $old_id);
 
       // Rename.
-      $config_test->id = $new_id;
+      $config_test->set('id', $new_id);
       $this->assertIdentical($config_test->id(), $new_id);
       $status = $config_test->save();
       $this->assertIdentical($status, SAVED_UPDATED);
diff --git a/core/modules/entity/entity.module b/core/modules/entity/entity.module
index cc22891..550127b 100644
--- a/core/modules/entity/entity.module
+++ b/core/modules/entity/entity.module
@@ -86,7 +86,7 @@ function entity_entity_bundle_rename($entity_type_id, $bundle_old, $bundle_new)
       $id = ConfigStorageController::getIDFromConfigName($id, $entity_type->getConfigPrefix());
       $display = entity_load('entity_view_display', $id);
       $new_id = $entity_type_id . '.' . $bundle_new . '.' . $display->mode;
-      $display->id = $new_id;
+      $display->set('id', $new_id);
       $display->bundle = $bundle_new;
       $display->save();
     }
@@ -100,7 +100,7 @@ function entity_entity_bundle_rename($entity_type_id, $bundle_old, $bundle_new)
       $id = ConfigStorageController::getIDFromConfigName($id, $entity_type->getConfigPrefix());
       $form_display = entity_load('entity_form_display', $id);
       $new_id = $entity_type_id . '.' . $bundle_new . '.' . $form_display->mode;
-      $form_display->id = $new_id;
+      $form_display->set('id', $new_id);
       $form_display->bundle = $bundle_new;
       $form_display->save();
     }
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
index 1a2bc5e..b33b3d9 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
@@ -23,7 +23,7 @@
    *
    * @var string
    */
-  public $id;
+  protected $id;
 
   /**
    * Entity type to be displayed.
@@ -198,7 +198,6 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $
    */
   public function toArray() {
     $names = array(
-      'id',
       'uuid',
       'targetEntityType',
       'bundle',
@@ -208,7 +207,9 @@ public function toArray() {
       'status',
       'dependencies'
     );
-    $properties = array();
+    $properties = array(
+      'id' => $this->id(),
+    );
     foreach ($names as $name) {
       $properties[$name] = $this->get($name);
     }
diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
index 31ea4e8..2f4035b 100644
--- a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php
@@ -104,7 +104,7 @@ public function testEntityGetDisplay() {
     // Check that entity_get_display() returns the correct object.
     $display = entity_get_display('entity_test', 'entity_test', 'default');
     $this->assertFalse($display->isNew());
-    $this->assertEqual($display->id, 'entity_test.entity_test.default');
+    $this->assertEqual($display->id(), 'entity_test.entity_test.default');
     $this->assertEqual($display->getComponent('component_1'), array('weight' => 10));
   }
 
@@ -279,10 +279,10 @@ public function testRenameDeleteBundle() {
     $this->assertFalse($old_form_display);
     $new_display = entity_load('entity_view_display', 'node.article_rename.default');
     $this->assertEqual('article_rename', $new_display->bundle);
-    $this->assertEqual('node.article_rename.default', $new_display->id);
+    $this->assertEqual('node.article_rename.default', $new_display->id());
     $new_form_display = entity_load('entity_form_display', 'node.article_rename.default');
     $this->assertEqual('article_rename', $new_form_display->bundle);
-    $this->assertEqual('node.article_rename.default', $new_form_display->id);
+    $this->assertEqual('node.article_rename.default', $new_form_display->id());
 
     $expected_dependencies = array(
       'entity' => array('field.instance.node.article_rename.body', 'node.type.article_rename'),
diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
index eb0477f..428222b 100644
--- a/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
+++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityFormDisplayTest.php
@@ -45,7 +45,7 @@ public function testEntityGetFromDisplay() {
     // Check that entity_get_form_display() returns the correct object.
     $form_display = entity_get_form_display('entity_test', 'entity_test', 'default');
     $this->assertFalse($form_display->isNew());
-    $this->assertEqual($form_display->id, 'entity_test.entity_test.default');
+    $this->assertEqual($form_display->id(), 'entity_test.entity_test.default');
     $this->assertEqual($form_display->getComponent('component_1'), array('weight' => 10));
   }
 
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index f0e280c..3069fdf 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -218,7 +218,7 @@ function field_entity_bundle_rename($entity_type, $bundle_old, $bundle_new) {
   foreach ($instances as $instance) {
     if ($instance->entity_type == $entity_type && $instance->bundle == $bundle_old) {
       $id_new = $instance->entity_type . '.' . $bundle_new . '.' . $instance->field_name;
-      $instance->id = $id_new;
+      $instance->set('id', $id_new);
       $instance->bundle = $bundle_new;
       $instance->allowBundleRename();
       $instance->save();
diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php
index 20ff0de..edb737a 100644
--- a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php
+++ b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php
@@ -239,7 +239,6 @@ public function id() {
    */
   public function toArray() {
     $names = array(
-      'id',
       'uuid',
       'status',
       'langcode',
@@ -254,7 +253,9 @@ public function toArray() {
       'indexes',
       'dependencies',
     );
-    $properties = array();
+    $properties = array(
+      'id' => $this->id(),
+    );
     foreach ($names as $name) {
       $properties[$name] = $this->get($name);
     }
diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php
index 2b8e87f..35b3775 100644
--- a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php
+++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php
@@ -283,7 +283,7 @@ public function __construct(array $values, $entity_type = 'field_instance_config
    * {@inheritdoc}
    */
   public function id() {
-    return $this->entity_type . '.' . $this->bundle . '.' . $this->field->name;
+    return $this->entity_type . '.' . $this->bundle . '.' . $this->field_name;
   }
 
   /**
@@ -291,7 +291,6 @@ public function id() {
    */
   public function toArray() {
     $names = array(
-      'id',
       'uuid',
       'status',
       'langcode',
@@ -307,7 +306,9 @@ public function toArray() {
       'settings',
       'dependencies',
     );
-    $properties = array();
+    $properties = array(
+      'id' => $this->id(),
+    );
     foreach ($names as $name) {
       $properties[$name] = $this->get($name);
     }
diff --git a/core/modules/field/lib/Drupal/field/FieldConfigStorageController.php b/core/modules/field/lib/Drupal/field/FieldConfigStorageController.php
index 7fb0866..fb8a8a5 100644
--- a/core/modules/field/lib/Drupal/field/FieldConfigStorageController.php
+++ b/core/modules/field/lib/Drupal/field/FieldConfigStorageController.php
@@ -135,7 +135,7 @@ public function loadByProperties(array $conditions = array()) {
 
       // When returning deleted fields, key the results by UUID since they can
       // include several fields with the same ID.
-      $key = $include_deleted ? $field->uuid : $field->id;
+      $key = $include_deleted ? $field->uuid() : $field->id();
       $matching_fields[$key] = $field;
     }
 
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
index d162cd3..edf1919 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php
@@ -115,7 +115,8 @@ public function testDefaultImages() {
       ->save();
 
     // Confirm the defaults are present on the article field settings form.
-    $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id/field");
+    $instance_id = $instance->id();
+    $this->drupalGet("admin/structure/types/manage/article/fields/$instance_id/field");
     $this->assertFieldByXpath(
       '//input[@name="field[settings][default_image][fid][fids]"]',
       $default_images['field']->id(),
@@ -125,7 +126,7 @@ public function testDefaultImages() {
       )
     );
     // Confirm the defaults are present on the article field edit form.
-    $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id");
+    $this->drupalGet("admin/structure/types/manage/article/fields/$instance_id");
     $this->assertFieldByXpath(
       '//input[@name="instance[settings][default_image][fid][fids]"]',
       $default_images['instance']->id(),
@@ -136,7 +137,7 @@ public function testDefaultImages() {
     );
 
     // Confirm the defaults are present on the page field settings form.
-    $this->drupalGet("admin/structure/types/manage/page/fields/$instance->id/field");
+    $this->drupalGet("admin/structure/types/manage/page/fields/$instance_id/field");
     $this->assertFieldByXpath(
       '//input[@name="field[settings][default_image][fid][fids]"]',
       $default_images['field']->id(),
@@ -146,7 +147,8 @@ public function testDefaultImages() {
       )
     );
     // Confirm the defaults are present on the page field edit form.
-    $this->drupalGet("admin/structure/types/manage/page/fields/$instance2->id");
+    $instance2_id = $instance2->id();
+    $this->drupalGet("admin/structure/types/manage/page/fields/$instance2_id");
     $this->assertFieldByXpath(
       '//input[@name="instance[settings][default_image][fid][fids]"]',
       $default_images['instance2']->id(),
@@ -185,7 +187,7 @@ public function testDefaultImages() {
     $field->save();
 
     // Confirm that the new default is used on the article field settings form.
-    $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id/field");
+    $this->drupalGet("admin/structure/types/manage/article/fields/$instance_id/field");
     $this->assertFieldByXpath(
       '//input[@name="field[settings][default_image][fid][fids]"]',
       $default_images['field_new']->id(),
@@ -221,7 +223,7 @@ public function testDefaultImages() {
 
     // Confirm the new field instance default is used on the article field
     // admin form.
-    $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id");
+    $this->drupalGet("admin/structure/types/manage/article/fields/$instance_id");
     $this->assertFieldByXpath(
       '//input[@name="instance[settings][default_image][fid][fids]"]',
       $default_images['instance_new']->id(),
@@ -259,7 +261,7 @@ public function testDefaultImages() {
     $instance->save();
 
     // Confirm the article field instance default has been removed.
-    $this->drupalGet("admin/structure/types/manage/article/fields/$instance->id");
+    $this->drupalGet("admin/structure/types/manage/article/fields/$instance_id");
     $this->assertFieldByXpath(
       '//input[@name="instance[settings][default_image][fid][fids]"]',
       '',
diff --git a/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php b/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php
index 4c5284f..41a5f91 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php
@@ -138,14 +138,15 @@ public function id() {
    */
   public function toArray() {
     $names = array(
-      'id',
       'uuid',
       'targetEntityType',
       'bundle',
       'types',
       'fieldMappings',
     );
-    $properties = array();
+    $properties = array(
+      'id' => $this->id(),
+    );
     foreach ($names as $name) {
       $properties[$name] = $this->get($name);
     }
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php
index be09ad8..b60312f 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php
@@ -248,7 +248,6 @@ public function testSave() {
    * @covers ::delete
    */
   public function testDelete() {
-    $this->entity->id = $this->randomName();
     $storage = $this->getMock('\Drupal\Core\Entity\EntityStorageControllerInterface');
     // Testing the argument of the delete() method consumes too much memory.
     $storage->expects($this->once())
