DDC-1517 - Fix EntityRepository#find() and EntityManager#getReference() breaking on invalid or missing identifiers.
This commit is contained in:
parent
5e3e8b3957
commit
619a31913a
@ -368,28 +368,38 @@ class EntityManager implements ObjectManager
|
||||
* without actually loading it, if the entity is not yet loaded.
|
||||
*
|
||||
* @param string $entityName The name of the entity type.
|
||||
* @param mixed $identifier The entity identifier.
|
||||
* @param mixed $id The entity identifier.
|
||||
* @return object The entity reference.
|
||||
*/
|
||||
public function getReference($entityName, $identifier)
|
||||
public function getReference($entityName, $id)
|
||||
{
|
||||
$class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
|
||||
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];
|
||||
}
|
||||
|
||||
// Check identity map first, if its already in there just return it.
|
||||
if ($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) {
|
||||
if ($entity = $this->unitOfWork->tryGetById($sortedId, $class->rootEntityName)) {
|
||||
return ($entity instanceof $class->name) ? $entity : null;
|
||||
}
|
||||
|
||||
if ($class->subClasses) {
|
||||
return $this->find($entityName, $identifier);
|
||||
return $this->find($entityName, $sortedId);
|
||||
}
|
||||
|
||||
if ( ! is_array($identifier)) {
|
||||
$identifier = array($class->identifier[0] => $identifier);
|
||||
if ( ! is_array($sortedId)) {
|
||||
$sortedId = array($class->identifier[0] => $sortedId);
|
||||
}
|
||||
|
||||
$entity = $this->proxyFactory->getProxy($class->name, $identifier);
|
||||
$this->unitOfWork->registerManaged($entity, $identifier, array());
|
||||
$entity = $this->proxyFactory->getProxy($class->name, $sortedId);
|
||||
$this->unitOfWork->registerManaged($entity, $sortedId, array());
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
@ -107,8 +107,19 @@ class EntityRepository implements ObjectRepository
|
||||
*/
|
||||
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($id, $this->_class->rootEntityName)) {
|
||||
if ($entity = $this->_em->getUnitOfWork()->tryGetById($sortedId, $this->_class->rootEntityName)) {
|
||||
if ( ! ($entity instanceof $this->_class->name)) {
|
||||
return null;
|
||||
}
|
||||
@ -120,22 +131,16 @@ class EntityRepository implements ObjectRepository
|
||||
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);
|
||||
}
|
||||
|
||||
switch ($lockMode) {
|
||||
case LockMode::NONE:
|
||||
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);
|
||||
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId);
|
||||
|
||||
case LockMode::OPTIMISTIC:
|
||||
if ( ! $this->_class->isVersioned) {
|
||||
throw OptimisticLockException::notVersioned($this->_entityName);
|
||||
}
|
||||
|
||||
$entity = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);
|
||||
$entity = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId);
|
||||
|
||||
$this->_em->getUnitOfWork()->lock($entity, $lockMode, $lockVersion);
|
||||
|
||||
@ -146,7 +151,7 @@ class EntityRepository implements ObjectRepository
|
||||
throw TransactionRequiredException::transactionRequired();
|
||||
}
|
||||
|
||||
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id, null, null, array(), $lockMode);
|
||||
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId, null, null, array(), $lockMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,4 +144,9 @@ class ORMException extends Exception
|
||||
return new self("Invalid repository class '".$className."'. ".
|
||||
"it must be a Doctrine\ORM\EntityRepository.");
|
||||
}
|
||||
|
||||
public static function missingIdentifierField($className, $fieldName)
|
||||
{
|
||||
return new self("The identifier $fieldName is missing for a query of " . $className);
|
||||
}
|
||||
}
|
||||
|
@ -92,4 +92,10 @@ class CompositePrimaryKeyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
$this->assertEquals(1, count($tours));
|
||||
}
|
||||
|
||||
public function testSpecifiyUnknownIdentifierPrimaryKeyFails()
|
||||
{
|
||||
$this->setExpectedException('Doctrine\ORM\ORMException', 'The identifier long is missing for a query of Doctrine\Tests\Models\Navigation\NavPointOfInterest');
|
||||
$poi = $this->_em->find('Doctrine\Tests\Models\Navigation\NavPointOfInterest', array('key1' => 100));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user