/**
  * @param string    $field
  * @param \StdClass $source
  * @param object    $entity
  *
  * @return array|Proxy|object
  * @throws HydrationException
  * @throws MappingException
  */
 private function hydrateAssociation($field, $entity, $source)
 {
     $accessor = new PropertyAccessor();
     $targetClassName = $this->metadata->getAssociationTargetClass($field);
     $mapping = $this->metadata->getAssociationMapping($field);
     $targetPersister = $this->manager->getUnitOfWork()->getEntityPersister($targetClassName);
     $targetMetadata = $this->manager->getClassMetadata($mapping['target']);
     $apiField = $mapping['api_field'];
     $field = $mapping['field'];
     if ($this->metadata->isSingleValuedAssociation($field)) {
         $identifiers = $this->metadata->getIdentifierValues($entity);
         if ($mapping['isOwningSide']) {
             try {
                 $value = $accessor->getValue($source, $apiField);
             } catch (NoSuchPropertyException $exception) {
                 if ($mapping['nullable']) {
                     return null;
                 }
                 throw new HydrationException(sprintf('Api field %s for property %s does not present in response', $apiField, $field));
             }
             if ($targetMetadata->isIdentifierComposite()) {
                 throw new HydrationException('Composite references not supported');
             }
             $targetIdsNames = $targetMetadata->getIdentifierFieldNames();
             $targetIdName = array_shift($targetIdsNames);
             $type = $this->manager->getConfiguration()->getTypeRegistry()->get($targetMetadata->getTypeOfField($targetIdName));
             $identifiers = [$targetIdName => $type->fromApiValue($value)];
         }
         return $targetPersister->getToOneEntity($mapping, $entity, $identifiers);
     }
     if ($this->metadata->isCollectionValuedAssociation($field)) {
         return $targetPersister->getOneToManyCollection($mapping, $entity);
     }
     throw new MappingException('Invalid metadata association type');
 }
 /**
  * Loads an entity of this persister's mapped class as part of a single-valued
  * association from another entity.
  *
  * @param array  $assoc        The association to load.
  * @param object $sourceEntity The entity that owns the association (not necessarily the "owning side").
  * @param array  $identifier   The identifier of the entity to load. Must be provided if
  *                             the association to load represents the owning side, otherwise
  *                             the identifier is derived from the $sourceEntity.
  *
  * @return object The loaded and managed entity instance or NULL if the entity can not be found.
  */
 public function loadOneToOneEntity(array $assoc, $sourceEntity, array $identifier = [])
 {
     if (false !== ($foundEntity = $this->manager->getUnitOfWork()->tryGetById($identifier, $assoc['target']))) {
         return $foundEntity;
     }
     // Get identifiers from entity if the entity is not the owning side
     if (!$assoc['isOwningSide']) {
         $identifier = $this->metadata->getIdentifierValues($sourceEntity);
     }
     return $this->loadById($identifier);
 }