diff --git a/lib/Doctrine/ORM/EntityNotFoundException.php b/lib/Doctrine/ORM/EntityNotFoundException.php index 18278f715..afe2f2242 100644 --- a/lib/Doctrine/ORM/EntityNotFoundException.php +++ b/lib/Doctrine/ORM/EntityNotFoundException.php @@ -28,10 +28,24 @@ namespace Doctrine\ORM; class EntityNotFoundException extends ORMException { /** - * Constructor. + * Static constructor. + * + * @param string $className + * @param string[] $id + * + * @return self */ - public function __construct($class) + public static function fromClassNameAndIdentifier($className, array $id) { - parent::__construct("Entity of type '{$class}' was not found."); + $ids = array(); + + foreach ($id as $key => $value) { + $ids[] = $key . '(' . $value . ')'; + } + + + return new self( + 'Entity of type \'' . $className . '\'' . ($ids ? ' for IDs ' . implode(', ', $ids) : '') . ' was not found' + ); } } diff --git a/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/lib/Doctrine/ORM/Proxy/ProxyFactory.php index 8d4cb5662..157ae643f 100644 --- a/lib/Doctrine/ORM/Proxy/ProxyFactory.php +++ b/lib/Doctrine/ORM/Proxy/ProxyFactory.php @@ -28,6 +28,7 @@ use Doctrine\Common\Proxy\ProxyGenerator; use Doctrine\ORM\Persisters\EntityPersister; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityNotFoundException; +use Doctrine\ORM\Utility\IdentifierFlattener; /** * This factory is used to create proxy objects for entities at runtime. @@ -54,6 +55,13 @@ class ProxyFactory extends AbstractProxyFactory */ private $proxyNs; + /** + * The IdentifierFlattener used for manipulating identifiers + * + * @var \Doctrine\ORM\Utility\IdentifierFlattener + */ + private $identifierFlattener; + /** * Initializes a new instance of the ProxyFactory class that is * connected to the given EntityManager. @@ -71,10 +79,10 @@ class ProxyFactory extends AbstractProxyFactory $proxyGenerator->setPlaceholder('baseProxyInterface', 'Doctrine\ORM\Proxy\Proxy'); parent::__construct($proxyGenerator, $em->getMetadataFactory(), $autoGenerate); - $this->em = $em; - $this->uow = $em->getUnitOfWork(); - $this->proxyNs = $proxyNs; - + $this->em = $em; + $this->uow = $em->getUnitOfWork(); + $this->proxyNs = $proxyNs; + $this->identifierFlattener = new IdentifierFlattener($this->uow, $em->getMetadataFactory()); } /** @@ -115,8 +123,9 @@ class ProxyFactory extends AbstractProxyFactory */ private function createInitializer(ClassMetadata $classMetadata, EntityPersister $entityPersister) { + $identifierFlattener = $this->identifierFlattener; if ($classMetadata->getReflectionClass()->hasMethod('__wakeup')) { - return function (BaseProxy $proxy) use ($entityPersister, $classMetadata) { + return function (BaseProxy $proxy) use ($entityPersister, $classMetadata, $identifierFlattener) { $initializer = $proxy->__getInitializer(); $cloner = $proxy->__getCloner(); @@ -138,17 +147,22 @@ class ProxyFactory extends AbstractProxyFactory $proxy->__setInitialized(true); $proxy->__wakeup(); - if (null === $entityPersister->loadById($classMetadata->getIdentifierValues($proxy), $proxy)) { + $identifier = $classMetadata->getIdentifierValues($proxy); + + if (null === $entityPersister->loadById($identifier, $proxy)) { $proxy->__setInitializer($initializer); $proxy->__setCloner($cloner); $proxy->__setInitialized(false); - throw new EntityNotFoundException($classMetadata->getName()); + throw EntityNotFoundException::fromClassNameAndIdentifier( + $classMetadata->getName(), + $identifierFlattener->flattenIdentifier($classMetadata, $identifier) + ); } }; } - return function (BaseProxy $proxy) use ($entityPersister, $classMetadata) { + return function (BaseProxy $proxy) use ($entityPersister, $classMetadata, $identifierFlattener) { $initializer = $proxy->__getInitializer(); $cloner = $proxy->__getCloner(); @@ -169,12 +183,17 @@ class ProxyFactory extends AbstractProxyFactory $proxy->__setInitialized(true); - if (null === $entityPersister->loadById($classMetadata->getIdentifierValues($proxy), $proxy)) { + $identifier = $classMetadata->getIdentifierValues($proxy); + + if (null === $entityPersister->loadById($identifier, $proxy)) { $proxy->__setInitializer($initializer); $proxy->__setCloner($cloner); $proxy->__setInitialized(false); - throw new EntityNotFoundException($classMetadata->getName()); + throw EntityNotFoundException::fromClassNameAndIdentifier( + $classMetadata->getName(), + $identifierFlattener->flattenIdentifier($classMetadata, $identifier) + ); } }; } @@ -191,19 +210,25 @@ class ProxyFactory extends AbstractProxyFactory */ private function createCloner(ClassMetadata $classMetadata, EntityPersister $entityPersister) { - return function (BaseProxy $proxy) use ($entityPersister, $classMetadata) { + $identifierFlattener = $this->identifierFlattener; + + return function (BaseProxy $proxy) use ($entityPersister, $classMetadata, $identifierFlattener) { if ($proxy->__isInitialized()) { return; } $proxy->__setInitialized(true); $proxy->__setInitializer(null); - - $class = $entityPersister->getClassMetadata(); - $original = $entityPersister->loadById($classMetadata->getIdentifierValues($proxy)); + + $class = $entityPersister->getClassMetadata(); + $identifier = $classMetadata->getIdentifierValues($proxy); + $original = $entityPersister->loadById($identifier); if (null === $original) { - throw new EntityNotFoundException($classMetadata->getName()); + throw EntityNotFoundException::fromClassNameAndIdentifier( + $classMetadata->getName(), + $identifierFlattener->flattenIdentifier($classMetadata, $identifier) + ); } foreach ($class->getReflectionClass()->getProperties() as $property) { diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 8789b5f81..e91ff3d12 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -1843,7 +1843,10 @@ class UnitOfWork implements PropertyChangedListener // If the identifier is ASSIGNED, it is NEW, otherwise an error // since the managed entity was not found. if ( ! $class->isIdentifierNatural()) { - throw new EntityNotFoundException($class->getName()); + throw EntityNotFoundException::fromClassNameAndIdentifier( + $class->getName(), + $this->identifierFlattener->flattenIdentifier($class, $id) + ); } $managedCopy = $this->newInstance($class); diff --git a/tests/Doctrine/Tests/ORM/EntityNotFoundExceptionTest.php b/tests/Doctrine/Tests/ORM/EntityNotFoundExceptionTest.php new file mode 100644 index 000000000..7dce1b171 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/EntityNotFoundExceptionTest.php @@ -0,0 +1,33 @@ + 'bar') + ); + + $this->assertInstanceOf('Doctrine\ORM\EntityNotFoundException', $exception); + $this->assertSame('Entity of type \'foo\' for IDs foo(bar) was not found', $exception->getMessage()); + + $exception = EntityNotFoundException::fromClassNameAndIdentifier( + 'foo', + array() + ); + + $this->assertInstanceOf('Doctrine\ORM\EntityNotFoundException', $exception); + $this->assertSame('Entity of type \'foo\' was not found', $exception->getMessage()); + } +}