diff --git a/src/Item/Field.php b/src/Item/Field.php
index 97637ad..6d69216 100644
--- a/src/Item/Field.php
+++ b/src/Item/Field.php
@@ -8,6 +8,7 @@
 namespace Drupal\search_api\Item;
 
 use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
 use Drupal\search_api\Entity\Index;
 use Drupal\search_api\IndexInterface;
 use Drupal\search_api\SearchApiException;
@@ -94,20 +95,6 @@ class Field implements \IteratorAggregate, FieldInterface {
   protected $labelPrefix;
 
   /**
-   * Whether this field should be hidden from the user.
-   *
-   * @var bool
-   */
-  protected $hidden;
-
-  /**
-   * The field's values.
-   *
-   * @var array
-   */
-  protected $values = array();
-
-  /**
    * The Search API data type of this field.
    *
    * @var string
@@ -115,25 +102,18 @@ class Field implements \IteratorAggregate, FieldInterface {
   protected $type;
 
   /**
-   * The original data type of this field.
+   * The boost assigned to this field, if any.
    *
-   * @var string
+   * @var float
    */
-  protected $originalType;
+  protected $boost;
 
   /**
-   * The state of this field in the index, whether indexed or not.
+   * Whether this field should be hidden from the user.
    *
    * @var bool
    */
-  protected $indexed;
-
-  /**
-   * The boost assigned to this field, if any.
-   *
-   * @var float
-   */
-  protected $boost;
+  protected $hidden;
 
   /**
    * Whether this field should always be enabled/indexed.
@@ -150,6 +130,20 @@ class Field implements \IteratorAggregate, FieldInterface {
   protected $typeLocked;
 
   /**
+   * The field's values.
+   *
+   * @var array
+   */
+  protected $values = array();
+
+  /**
+   * The original data type of this field.
+   *
+   * @var string
+   */
+  protected $originalType;
+
+  /**
    * Constructs a Field object.
    *
    * @param \Drupal\search_api\IndexInterface $index
@@ -196,12 +190,6 @@ class Field implements \IteratorAggregate, FieldInterface {
       'datasource_id' => $this->getDatasourceId(),
       'property_path' => $this->getPropertyPath(),
       'type' => $this->getType(),
-      // @todo Check whether YAML/schema magic will add those anyways, or
-      //   whether them not being present is a problem.
-//      'boost' => $this->getBoost(),
-//      'indexed_locked' => $this->isIndexedLocked(),
-//      'type_locked' => $this->isTypeLocked(),
-//      'hidden' => $this->isHidden(),
     );
     if ($this->getBoost() != 1.0) {
       $settings['boost'] = $this->getBoost();
@@ -247,12 +235,6 @@ class Field implements \IteratorAggregate, FieldInterface {
    * {@inheritdoc}
    */
   public function getPropertyPath() {
-    if (!isset($this->propertyPath)) {
-      $fields = $this->getIndex()->getFields();
-      if (isset($fields[$this->getFieldIdentifier()]) && $fields[$this->getFieldIdentifier()] != $this) {
-        $this->propertyPath = $fields[$this->getFieldIdentifier()]->getPropertyPath();
-      }
-    }
     return $this->propertyPath;
   }
 
@@ -357,22 +339,48 @@ class Field implements \IteratorAggregate, FieldInterface {
   /**
    * {@inheritdoc}
    */
-  // @todo This currently only works for unnested fields, since
-  //   Index::getPropertyDefinitions() won't return any nested ones.
   public function getDataDefinition() {
     if (!isset($this->dataDefinition)) {
-      $definitions = $this->index->getPropertyDefinitions($this->datasourceId);
-      if (!isset($definitions[$this->propertyPath])) {
-        $args['@field'] = $this->fieldIdentifier;
-        $args['%index'] = $this->index->label();
-        throw new SearchApiException(new FormattableMarkup('Could not retrieve data definition for field "@field" on index %index.', $args));
+      $definitions = $this->index->getPropertyDefinitions($this->getDatasourceId());
+      $definition = $this->getNestedDefinition($definitions, explode(':', $this->getPropertyPath()));
+      if (!$definition) {
+        $args['%field'] = $this->getLabel();
+        $args['%index'] = $this->getIndex()->label();
+        throw new SearchApiException(new FormattableMarkup('Could not retrieve data definition for field %field on index %index.', $args));
       }
-      $this->dataDefinition = $definitions[$this->propertyPath];
+      $this->dataDefinition = $definition;
     }
     return $this->dataDefinition;
   }
 
   /**
+   * Retrieves a nested property definition from an array of definitions.
+   *
+   * @param \Drupal\Core\TypedData\DataDefinitionInterface[] $properties
+   *   The given array of base definitions.
+   * @param string[] $keys
+   *   An array of keys to apply to the definitions to arrive at the one that
+   *   should be returned.
+   *
+   * @return \Drupal\Core\TypedData\DataDefinitionInterface|null
+   *   The requested property definition, or NULL if it could not be found.
+   */
+  protected function getNestedDefinition(array $properties, array $keys) {
+    $key = array_shift($keys);
+    if (!isset($properties[$key])) {
+      return NULL;
+    }
+    $property = Utility::getInnerProperty($properties[$key]);
+    if (!$keys) {
+      return $property;
+    }
+    if (!$property instanceof ComplexDataDefinitionInterface) {
+      return NULL;
+    }
+    return $this->getNestedDefinition($property->getPropertyDefinitions(), $keys);
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getType() {
@@ -383,6 +391,11 @@ class Field implements \IteratorAggregate, FieldInterface {
    * {@inheritdoc}
    */
   public function setType($type) {
+    if ($this->isTypeLocked()) {
+      $args['%field'] = $this->getLabel();
+      $args['%index'] = $this->getIndex()->label();
+      throw new SearchApiException(new FormattableMarkup('Trying to change the type of field %field on index %index, which is locked.', $args));
+    }
     $this->type = $type;
     return $this;
   }
@@ -438,11 +451,7 @@ class Field implements \IteratorAggregate, FieldInterface {
    * {@inheritdoc}
    */
   public function getBoost() {
-    if (!isset($this->boost)) {
-      $fields = $this->index->getFieldSettings();
-      $this->boost = isset($fields[$this->fieldIdentifier]['boost']) ? (float) $fields[$this->fieldIdentifier]['boost'] : 1.0;
-    }
-    return $this->boost;
+    return isset($this->boost) ? $this->boost : 1.0;
   }
 
   /**
diff --git a/src/Item/FieldInterface.php b/src/Item/FieldInterface.php
index 57e3f58..873463d 100644
--- a/src/Item/FieldInterface.php
+++ b/src/Item/FieldInterface.php
@@ -95,9 +95,6 @@ interface FieldInterface extends \Traversable {
    *
    * @return string
    *   The property path.
-   *
-   * @throws \Drupal\search_api\SearchApiException
-   *   Thrown if no property path was set before and it couldn't be loaded.
    */
   public function getPropertyPath();
 
@@ -235,6 +232,9 @@ interface FieldInterface extends \Traversable {
    *   The data type of the field.
    *
    * @return $this
+   *
+   * @throws \Drupal\search_api\SearchApiException
+   *   Thrown if the type of this field is locked.
    */
   public function setType($type);
 
