/** * {@inheritDoc} */ public function find($id, $lockMode = LockMode::NONE, $lockVersion = null) { // Check identity map first if ($entity = $this->_em->getUnitOfWork()->tryGetById($id, $this->_class->rootEntityName)) { if (!$entity instanceof $this->_class->name) { return null; } if ($lockMode != LockMode::NONE) { $this->_em->lock($entity, $lockMode, $lockVersion); } return $entity; // Hit! } if (!is_array($id) || count($id) <= 1) { // @todo FIXME: Not correct. Relies on specific order. $value = is_array($id) ? array_values($id) : array($id); $id = array_combine($this->_class->identifier, $value); } $id = $this->addInstanceFilter($id); if ($lockMode == LockMode::NONE) { return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id); } else { if ($lockMode == LockMode::OPTIMISTIC) { if (!$this->_class->isVersioned) { throw OptimisticLockException::notVersioned($this->_entityName); } $entity = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id); $this->_em->getUnitOfWork()->lock($entity, $lockMode, $lockVersion); return $entity; } else { if (!$this->_em->getConnection()->isTransactionActive()) { throw TransactionRequiredException::transactionRequired(); } return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id, null, null, array(), $lockMode); } } }
/** * Set the lock mode for this Query. * * @see \Doctrine\DBAL\LockMode * @param int $lockMode * @return Query */ public function setLockMode($lockMode) { if (in_array($lockMode, array(LockMode::PESSIMISTIC_READ, LockMode::PESSIMISTIC_WRITE))) { if (!$this->_em->getConnection()->isTransactionActive()) { throw TransactionRequiredException::transactionRequired(); } } $this->setHint(self::HINT_LOCK_MODE, $lockMode); return $this; }
/** * 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_object($id) && $this->metadataFactory->hasMetadataFor(ClassUtils::getClass($id))) { $id = $this->unitOfWork->getSingleIdentifierValue($id); if ($id === null) { throw ORMInvalidArgumentException::invalidIdentifierBindingEntity(); } } if (!is_array($id)) { $id = array($class->identifier[0] => $id); } $sortedId = array(); foreach ($class->identifier as $identifier) { if (!isset($id[$identifier])) { throw ORMException::missingIdentifierField($class->name, $identifier); } $sortedId[$identifier] = $id[$identifier]; } $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::NONE === $lockMode: case LockMode::PESSIMISTIC_READ === $lockMode: case LockMode::PESSIMISTIC_WRITE === $lockMode: if (!$this->getConnection()->isTransactionActive()) { throw TransactionRequiredException::transactionRequired(); } return $persister->load($sortedId, null, null, array(), $lockMode); default: return $persister->loadById($sortedId); } }
/** * Acquire a lock on the given entity. * * @param object $entity * @param int $lockMode * @param int $lockVersion * * @return void * * @throws ORMInvalidArgumentException * @throws TransactionRequiredException * @throws OptimisticLockException */ public function lock($entity, $lockMode, $lockVersion = null) { if ($entity === null) { throw new \InvalidArgumentException("No entity passed to UnitOfWork#lock()."); } if ($this->getEntityState($entity, self::STATE_DETACHED) != self::STATE_MANAGED) { throw ORMInvalidArgumentException::entityNotManaged($entity); } $class = $this->em->getClassMetadata(get_class($entity)); switch (true) { case LockMode::OPTIMISTIC === $lockMode: if (!$class->isVersioned) { throw OptimisticLockException::notVersioned($class->name); } if ($lockVersion === null) { return; } $entityVersion = $class->reflFields[$class->versionField]->getValue($entity); if ($entityVersion != $lockVersion) { throw OptimisticLockException::lockFailedVersionMismatch($entity, $lockVersion, $entityVersion); } break; case LockMode::NONE === $lockMode: case LockMode::PESSIMISTIC_READ === $lockMode: case LockMode::PESSIMISTIC_WRITE === $lockMode: if (!$this->em->getConnection()->isTransactionActive()) { throw TransactionRequiredException::transactionRequired(); } $oid = spl_object_hash($entity); $this->getEntityPersister($class->name)->lock(array_combine($class->getIdentifierFieldNames(), $this->entityIdentifiers[$oid]), $lockMode); break; default: // Do nothing } }
/** * Acquire a lock on the given entity. * * @param object $entity * @param int $lockMode * @param int $lockVersion */ public function lock($entity, $lockMode, $lockVersion = null) { if ($this->getEntityState($entity) != self::STATE_MANAGED) { throw new InvalidArgumentException("Entity is not MANAGED."); } $entityName = get_class($entity); $class = $this->em->getClassMetadata($entityName); if ($lockMode == \Doctrine\DBAL\LockMode::OPTIMISTIC) { if (!$class->isVersioned) { throw OptimisticLockException::notVersioned($entityName); } if ($lockVersion != null) { $entityVersion = $class->reflFields[$class->versionField]->getValue($entity); if ($entityVersion != $lockVersion) { throw OptimisticLockException::lockFailedVersionMissmatch($entity, $lockVersion, $entityVersion); } } } else { if (in_array($lockMode, array(\Doctrine\DBAL\LockMode::PESSIMISTIC_READ, \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE))) { if (!$this->em->getConnection()->isTransactionActive()) { throw TransactionRequiredException::transactionRequired(); } $oid = spl_object_hash($entity); $this->getEntityPersister($class->name)->lock(array_combine($class->getIdentifierFieldNames(), $this->entityIdentifiers[$oid]), $lockMode); } } }
/** * Finds an entity by its primary key / identifier. * * @param $id The identifier. * @param int $lockMode * @param int $lockVersion * @return object The entity. */ public function find($id, $lockMode = LockMode::NONE, $lockVersion = null) { if (!is_array($id)) { $id = array($this->_class->identifier[0] => $id); } $sortedId = array(); foreach ($this->_class->identifier as $identifier) { if (!isset($id[$identifier])) { throw ORMException::missingIdentifierField($this->_class->name, $identifier); } $sortedId[$identifier] = $id[$identifier]; } // Check identity map first if (($entity = $this->_em->getUnitOfWork()->tryGetById($sortedId, $this->_class->rootEntityName)) !== false) { if (!$entity instanceof $this->_class->name) { return null; } if ($lockMode !== LockMode::NONE) { $this->_em->lock($entity, $lockMode, $lockVersion); } return $entity; // Hit! } $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName); switch ($lockMode) { case LockMode::NONE: return $persister->load($sortedId); case LockMode::OPTIMISTIC: if (!$this->_class->isVersioned) { throw OptimisticLockException::notVersioned($this->_entityName); } $entity = $persister->load($sortedId); $this->_em->getUnitOfWork()->lock($entity, $lockMode, $lockVersion); return $entity; default: if (!$this->_em->getConnection()->isTransactionActive()) { throw TransactionRequiredException::transactionRequired(); } return $persister->load($sortedId, null, null, array(), $lockMode); } }