/**
  * {@inheritdoc}
  */
 public function setErrors($errors)
 {
     // A document containing errors must not have primary data
     if (null !== $errors) {
         $this->clearData();
     }
     parent::setErrors($errors);
 }
 /**
  * @param AbstractDocument $document
  * @param object $data
  * @param array $included
  * @param array|null $includeRelationships
  * @return ResourceObject
  * @throws \Exception
  */
 public function buildResourceObject(AbstractDocument $document, $data, array $included = array(), $includeRelationships = null)
 {
     list(, $idValue, $objectType) = $this->getResourceInfo($data);
     $resourceObject = new ResourceObject($idValue, $objectType);
     $objectMetadata = $this->getClassMetadata($data);
     /** @var array $serializedData */
     /** @var ClassHierarchyMetadata|MergeableClassMetadata $serializationMetadata */
     /** @var PropertyNamingStrategyInterface $namingStrategy */
     list($serializedData, $serializationMetadata, $namingStrategy) = $this->getSerializationData($data);
     foreach ($serializationMetadata->propertyMetadata as $propertyMetadata) {
         /** @var PropertyMetadata $propertyMetadata */
         // Translate the object property name into the serialized format. We need to know how the property
         // is named because we use this name to read the value from the serialized object representation.
         $serializedPropertyName = $propertyMetadata->serializedName;
         if (null === $serializedPropertyName) {
             $serializedPropertyName = $namingStrategy->translateName($propertyMetadata);
         }
         // Get the serialized value. Reading the serialized value ensures that all serializer settings and
         // annotations are respected before transforming the data into the json api format.
         if (!isset($serializedData[$serializedPropertyName])) {
             throw new \RuntimeException("Unable to read property '{$serializedPropertyName}'");
         }
         $serializedPropertyValue = $serializedData[$serializedPropertyName];
         // Identifiers must not be part of the attributes or relationships list
         if ($objectMetadata->isIdentifier($propertyMetadata->name)) {
             continue;
         }
         // Handle doctrine to-one/to-many relationships according to the json api specification.
         if ($objectMetadata->hasAssociation($propertyMetadata->name)) {
             // Skip the current relationship if a list of allowed relationships is explicitly set and the current
             // property is not included in the list.
             if (is_array($includeRelationships) && !in_array($serializedPropertyName, $includeRelationships)) {
                 continue;
             }
             if ($objectMetadata->isSingleValuedAssociation($propertyMetadata->name)) {
                 $relationship = new ToOneRelationship();
                 $associationValue = $propertyMetadata->getValue($data);
                 $relationship->setData($this->buildResourceIdentifier($associationValue));
                 $resourceObject->setRelationship($serializedPropertyName, $relationship);
                 if (isset($included[$serializedPropertyName])) {
                     $document->addIncluded($this->buildResourceObject($document, $associationValue, $included[$serializedPropertyName], array_keys($included[$serializedPropertyName])));
                 }
             } else {
                 if ($objectMetadata->isCollectionValuedAssociation($propertyMetadata->name)) {
                     $relationship = new ToManyRelationship();
                     foreach ($propertyMetadata->getValue($data) as $associationValue) {
                         $relationship->addData($this->buildResourceIdentifier($associationValue));
                         if (isset($included[$serializedPropertyName])) {
                             $document->addIncluded($this->buildResourceObject($document, $associationValue, $included[$serializedPropertyName], array_keys($included[$serializedPropertyName])));
                         }
                     }
                     $resourceObject->setRelationship($serializedPropertyName, $relationship);
                 }
             }
         } else {
             // All values that are no relationship must be added to the attributes list
             $resourceObject->setAttribute($serializedPropertyName, $serializedPropertyValue);
         }
     }
     return $resourceObject;
 }