1
0
mirror of synced 2025-01-19 15:01:40 +03:00

Merge branch 'feature/#1240-include-identifiers-in-exception-messages'

Close #1240
This commit is contained in:
Marco Pivetta 2015-01-13 02:56:06 +01:00
commit 5630c37b35
4 changed files with 94 additions and 19 deletions

View File

@ -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'
);
}
}

View File

@ -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 <tt>ProxyFactory</tt> class that is
* connected to the given <tt>EntityManager</tt>.
@ -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) {

View File

@ -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);

View File

@ -0,0 +1,33 @@
<?php
namespace Doctrine\Tests\ORM;
use Doctrine\ORM\EntityNotFoundException;
use PHPUnit_Framework_TestCase;
/**
* Tests for {@see \Doctrine\ORM\EntityNotFoundException}
*
* @covers \Doctrine\ORM\EntityNotFoundException
*/
class EntityNotFoundExceptionTest extends PHPUnit_Framework_TestCase
{
public function testFromClassNameAndIdentifier()
{
$exception = EntityNotFoundException::fromClassNameAndIdentifier(
'foo',
array('foo' => '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());
}
}