1
0
mirror of synced 2025-01-22 08:11:40 +03:00

Adding fix and tests for DDC-1734

This commit is contained in:
Marco Pivetta 2013-01-06 14:56:11 +01:00
parent 8272ffd23f
commit 271f5cf033
6 changed files with 149 additions and 3 deletions

View File

@ -25,6 +25,7 @@ use Doctrine\ORM\EntityNotFoundException;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Common\Proxy\Proxy;
use Doctrine\Common\Proxy\ProxyGenerator;
use Doctrine\ORM\ORMInvalidArgumentException;
/**
* This factory is used to create proxy objects for entities at runtime.
@ -123,6 +124,31 @@ class ProxyFactory
return $proxy;
}
/**
* @param \Doctrine\Common\Proxy\Proxy $proxy
*
* @return \Doctrine\Common\Proxy\Proxy
*
* @throws \Doctrine\ORM\ORMInvalidArgumentException
*/
public function resetUninitializedProxy(Proxy $proxy)
{
if ($proxy->__isInitialized()) {
throw new ORMInvalidArgumentException('Provided proxy must not be initialized');
}
$className = $this->em->getClassMetadata(get_class($proxy))->getName();
if ( ! isset($this->definitions[$className])) {
$this->initProxyDefinitions($className);
}
$proxy->__setInitializer($this->definitions[$className]['initializer']);
$proxy->__setCloner($this->definitions[$className]['cloner']);
return $proxy;
}
/**
* Generates proxy classes for all given classes.
*
@ -179,8 +205,9 @@ class ProxyFactory
*/
private function initProxyDefinitions($className)
{
$fqcn = ClassUtils::generateProxyClassName($className, $this->proxyNs);
$classMetadata = $this->em->getClassMetadata($className);
$className = $classMetadata->getName();
$fqcn = ClassUtils::generateProxyClassName($className, $this->proxyNs);
if ( ! class_exists($fqcn, false)) {
$generator = $this->getProxyGenerator();

View File

@ -1769,7 +1769,8 @@ class UnitOfWork implements PropertyChangedListener
$managedCopy = $entity;
if ($this->getEntityState($entity, self::STATE_DETACHED) !== self::STATE_MANAGED) {
if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
if ($entity instanceof Proxy && ! $entity->__isInitialized()) {
$this->em->getProxyFactory()->resetUninitializedProxy($entity);
$entity->__load();
}

@ -1 +1 @@
Subproject commit c2b45fdb2757492e75abaab119164aaf311cd395
Subproject commit 0aa165610e2fdd6617e0e2b91c35fedf92aea2f7

View File

@ -0,0 +1,37 @@
<?php
namespace Doctrine\Tests\Models\DDC1734;
/**
* @Entity
*/
class DDC1734Article
{
/**
* @Id @Column(type="integer")
* @GeneratedValue
*/
protected $id;
/**
* @Column(type="string")
*/
protected $name;
public function __construct($name)
{
$this->name = $name;
}
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
}

View File

@ -0,0 +1,78 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\DDC1734\DDC1734Article;
require_once __DIR__ . '/../../../TestInit.php';
class DDC1734Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('ddc1734');
parent::setUp();
}
/**
* This test is DDC-1734 minus the serialization, i.e. it works
* @group DDC-1734
*/
public function testMergeWorksOnNonSerializedProxies()
{
$article = new DDC1734Article("Foo");
$this->_em->persist($article);
$this->_em->flush();
// Get a proxy of the entity
$this->_em->clear();
$proxy = $this->getProxy($article);
$this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $proxy);
$this->assertFalse($proxy->__isInitialized__);
// Detach
$this->_em->detach($proxy);
$this->_em->clear();
// Merge
$proxy = $this->_em->merge($proxy);
$this->assertEquals("Foo", $proxy->getName(), "The entity is broken");
}
/**
* This test reproduces DDC-1734 which is:
* - A non-initialized proxy is detached and serialized (the identifier of the proxy is *not* serialized)
* - the object is deserialized and merged (to turn into an entity)
* - the entity is broken because it has no identifier and no field defined
* @group DDC-1734
*/
public function testMergeWorksOnSerializedProxies()
{
$article = new DDC1734Article("Foo");
$this->_em->persist($article);
$this->_em->flush();
// Get a proxy of the entity
$this->_em->clear();
$proxy = $this->getProxy($article);
$this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $proxy);
$this->assertFalse($proxy->__isInitialized());
// Detach and serialize
$this->_em->detach($proxy);
$serializedProxy = serialize($proxy);
$this->_em->clear();
// Unserialize and merge
/** @var $unserializedProxy DDC1734Article */
$unserializedProxy = unserialize($serializedProxy);
// Merge
$unserializedProxy = $this->_em->merge($unserializedProxy);
$this->assertEquals("Foo", $unserializedProxy->getName(), "The entity is broken");
}
private function getProxy($object)
{
$metadataFactory = $this->_em->getMetadataFactory();
$identifier = $metadataFactory->getMetadataFor(get_class($object))->getIdentifierValues($object);
$proxyFactory = $this->_em->getProxyFactory();
return $proxyFactory->getProxy(get_class($object), $identifier);
}
}

View File

@ -134,6 +134,9 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
'Doctrine\Tests\Models\DDC117\DDC117Editor',
'Doctrine\Tests\Models\DDC117\DDC117Link',
),
'ddc1734' => array(
'Doctrine\Tests\Models\DDC1734\DDC1734Article',
),
'stockexchange' => array(
'Doctrine\Tests\Models\StockExchange\Bond',
'Doctrine\Tests\Models\StockExchange\Stock',