Adding fix and tests for DDC-1734
This commit is contained in:
parent
8272ffd23f
commit
271f5cf033
@ -25,6 +25,7 @@ use Doctrine\ORM\EntityNotFoundException;
|
|||||||
use Doctrine\Common\Util\ClassUtils;
|
use Doctrine\Common\Util\ClassUtils;
|
||||||
use Doctrine\Common\Proxy\Proxy;
|
use Doctrine\Common\Proxy\Proxy;
|
||||||
use Doctrine\Common\Proxy\ProxyGenerator;
|
use Doctrine\Common\Proxy\ProxyGenerator;
|
||||||
|
use Doctrine\ORM\ORMInvalidArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This factory is used to create proxy objects for entities at runtime.
|
* This factory is used to create proxy objects for entities at runtime.
|
||||||
@ -123,6 +124,31 @@ class ProxyFactory
|
|||||||
return $proxy;
|
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.
|
* Generates proxy classes for all given classes.
|
||||||
*
|
*
|
||||||
@ -179,8 +205,9 @@ class ProxyFactory
|
|||||||
*/
|
*/
|
||||||
private function initProxyDefinitions($className)
|
private function initProxyDefinitions($className)
|
||||||
{
|
{
|
||||||
$fqcn = ClassUtils::generateProxyClassName($className, $this->proxyNs);
|
|
||||||
$classMetadata = $this->em->getClassMetadata($className);
|
$classMetadata = $this->em->getClassMetadata($className);
|
||||||
|
$className = $classMetadata->getName();
|
||||||
|
$fqcn = ClassUtils::generateProxyClassName($className, $this->proxyNs);
|
||||||
|
|
||||||
if ( ! class_exists($fqcn, false)) {
|
if ( ! class_exists($fqcn, false)) {
|
||||||
$generator = $this->getProxyGenerator();
|
$generator = $this->getProxyGenerator();
|
||||||
|
@ -1769,7 +1769,8 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
$managedCopy = $entity;
|
$managedCopy = $entity;
|
||||||
|
|
||||||
if ($this->getEntityState($entity, self::STATE_DETACHED) !== self::STATE_MANAGED) {
|
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();
|
$entity->__load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
lib/vendor/doctrine-common
vendored
2
lib/vendor/doctrine-common
vendored
@ -1 +1 @@
|
|||||||
Subproject commit c2b45fdb2757492e75abaab119164aaf311cd395
|
Subproject commit 0aa165610e2fdd6617e0e2b91c35fedf92aea2f7
|
37
tests/Doctrine/Tests/Models/DDC1734/DDC1734Article.php
Normal file
37
tests/Doctrine/Tests/Models/DDC1734/DDC1734Article.php
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
78
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1734Test.php
Normal file
78
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1734Test.php
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -134,6 +134,9 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
|||||||
'Doctrine\Tests\Models\DDC117\DDC117Editor',
|
'Doctrine\Tests\Models\DDC117\DDC117Editor',
|
||||||
'Doctrine\Tests\Models\DDC117\DDC117Link',
|
'Doctrine\Tests\Models\DDC117\DDC117Link',
|
||||||
),
|
),
|
||||||
|
'ddc1734' => array(
|
||||||
|
'Doctrine\Tests\Models\DDC1734\DDC1734Article',
|
||||||
|
),
|
||||||
'stockexchange' => array(
|
'stockexchange' => array(
|
||||||
'Doctrine\Tests\Models\StockExchange\Bond',
|
'Doctrine\Tests\Models\StockExchange\Bond',
|
||||||
'Doctrine\Tests\Models\StockExchange\Stock',
|
'Doctrine\Tests\Models\StockExchange\Stock',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user