/** * Processes an entity instance to extract their identifier values. * * @param object $entity The entity instance. * * @return mixed A scalar value. * * @throws \Doctrine\ORM\ORMInvalidArgumentException */ public function getSingleIdentifierValue($entity) { $class = $this->em->getClassMetadata(get_class($entity)); if ($class->isIdentifierComposite) { throw ORMInvalidArgumentException::invalidCompositeIdentifier(); } $values = $this->isInIdentityMap($entity) ? $this->getEntityIdentifier($entity) : $class->getIdentifierValues($entity); return isset($values[$class->identifier[0]]) ? $values[$class->identifier[0]] : null; }
/** * Finds an Entity by its identifier. * * @param string $entityName The class name of the entity to find. * @param mixed $id The identity of the entity to find. * @param integer|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants * or NULL if no specific lock mode should be used * during the search. * @param integer|null $lockVersion The version of the entity to find when using * optimistic locking. * * @return object|null The entity instance or NULL if the entity can not be found. * * @throws OptimisticLockException * @throws ORMInvalidArgumentException * @throws TransactionRequiredException * @throws ORMException */ public function find($entityName, $id, $lockMode = null, $lockVersion = null) { $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\')); if (!is_array($id)) { if ($class->isIdentifierComposite) { throw ORMInvalidArgumentException::invalidCompositeIdentifier(); } $id = [$class->identifier[0] => $id]; } foreach ($id as $i => $value) { if (is_object($value) && $this->metadataFactory->hasMetadataFor(ClassUtils::getClass($value))) { $id[$i] = $this->unitOfWork->getSingleIdentifierValue($value); if ($id[$i] === null) { throw ORMInvalidArgumentException::invalidIdentifierBindingEntity(); } } } $sortedId = []; foreach ($class->identifier as $identifier) { if (!isset($id[$identifier])) { throw ORMException::missingIdentifierField($class->name, $identifier); } $sortedId[$identifier] = $id[$identifier]; unset($id[$identifier]); } if ($id) { throw ORMException::unrecognizedIdentifierFields($class->name, array_keys($id)); } $unitOfWork = $this->getUnitOfWork(); // Check identity map first if (($entity = $unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) { if (!$entity instanceof $class->name) { return null; } switch (true) { case LockMode::OPTIMISTIC === $lockMode: $this->lock($entity, $lockMode, $lockVersion); break; case LockMode::NONE === $lockMode: case LockMode::PESSIMISTIC_READ === $lockMode: case LockMode::PESSIMISTIC_WRITE === $lockMode: $persister = $unitOfWork->getEntityPersister($class->name); $persister->refresh($sortedId, $entity, $lockMode); break; } return $entity; // Hit! } $persister = $unitOfWork->getEntityPersister($class->name); switch (true) { case LockMode::OPTIMISTIC === $lockMode: if (!$class->isVersioned) { throw OptimisticLockException::notVersioned($class->name); } $entity = $persister->load($sortedId); $unitOfWork->lock($entity, $lockMode, $lockVersion); return $entity; case LockMode::PESSIMISTIC_READ === $lockMode: case LockMode::PESSIMISTIC_WRITE === $lockMode: if (!$this->getConnection()->isTransactionActive()) { throw TransactionRequiredException::transactionRequired(); } return $persister->load($sortedId, null, null, [], $lockMode); default: return $persister->loadById($sortedId); } }