diff --git a/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/lib/Doctrine/ORM/Proxy/ProxyFactory.php index fe19c7d71e1..2ba41caba72 100644 --- a/lib/Doctrine/ORM/Proxy/ProxyFactory.php +++ b/lib/Doctrine/ORM/Proxy/ProxyFactory.php @@ -21,6 +21,7 @@ use ReflectionProperty; use Symfony\Component\VarExporter\ProxyHelper; use Symfony\Component\VarExporter\VarExporter; +use Throwable; use function array_flip; use function str_replace; @@ -204,7 +205,17 @@ private function createInitializer(ClassMetadata $classMetadata, EntityPersister $identifier = $classMetadata->getIdentifierValues($proxy); - if ($entityPersister->loadById($identifier, $proxy) === null) { + try { + $entity = $entityPersister->loadById($identifier, $proxy); + } catch (Throwable $exception) { + $proxy->__setInitializer($initializer); + $proxy->__setCloner($cloner); + $proxy->__setInitialized(false); + + throw $exception; + } + + if ($entity === null) { $proxy->__setInitializer($initializer); $proxy->__setCloner($cloner); $proxy->__setInitialized(false); diff --git a/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php b/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php index 8342058a701..1801f36806c 100644 --- a/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php @@ -7,6 +7,7 @@ use Doctrine\Common\EventManager; use Doctrine\Common\Proxy\Proxy as CommonProxy; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Exception\ConnectionException; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\ORM\EntityNotFoundException; use Doctrine\ORM\Mapping\ClassMetadata; @@ -145,6 +146,38 @@ public function testFailedProxyLoadingDoesNotMarkTheProxyAsInitialized(): void self::assertFalse($proxy->__isInitialized()); } + public function testExceptionOnProxyLoadingDoesNotMarkTheProxyAsInitialized(): void + { + $persister = $this + ->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['load', 'getClassMetadata']) + ->disableOriginalConstructor() + ->getMock(); + $this->uowMock->setEntityPersister(ECommerceFeature::class, $persister); + + $proxy = $this->proxyFactory->getProxy(ECommerceFeature::class, ['id' => 42]); + assert($proxy instanceof Proxy); + + $exception = $this + ->getMockBuilder(ConnectionException::class) + ->disableOriginalConstructor() + ->getMock(); + + $persister + ->expects(self::atLeastOnce()) + ->method('load') + ->will(self::throwException($exception)); + + try { + $proxy->getDescription(); + self::fail('An exception was expected to be raised'); + } catch (ConnectionException $exception) { + } + + self::assertFalse($proxy->__isInitialized(), 'The proxy should not be initialized'); + self::assertInstanceOf(Closure::class, $proxy->__getInitializer(), 'The initializer wasn\'t removed'); + self::assertInstanceOf(Closure::class, $proxy->__getCloner(), 'The cloner wasn\'t removed'); + } + /** @group DDC-2432 */ public function testFailedProxyCloningDoesNotMarkTheProxyAsInitialized(): void {