1
0
mirror of synced 2025-01-10 11:07:10 +03:00

Merge branch 'hotfix/#470-DDC-54-postLoad-deferred-event-triggering-tests'

Close #470
This commit is contained in:
Marco Pivetta 2015-01-13 01:43:44 +01:00
commit 14c3adbec0
4 changed files with 143 additions and 2 deletions

View File

@ -184,6 +184,14 @@ the life-time of their registered entities.
invoked, after all references to entities have been removed from the unit of invoked, after all references to entities have been removed from the unit of
work. This event is not a lifecycle callback. work. This event is not a lifecycle callback.
.. warning::
Note that, when using ``Doctrine\ORM\AbstractQuery#iterate()``, ``postLoad``
events will be executed immediately after objects are being hydrated, and therefore
associations are not guaranteed to be initialized. It is not safe to combine
usage of ``Doctrine\ORM\AbstractQuery#iterate()`` and ``postLoad`` event
handlers.
.. warning:: .. warning::
Note that the postRemove event or any events triggered after an entity removal Note that the postRemove event or any events triggered after an entity removal

View File

@ -24,6 +24,9 @@ use PDO;
use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use Doctrine\ORM\Events;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PostLoadEventDispatcher;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Proxy\Proxy; use Doctrine\ORM\Proxy\Proxy;
@ -522,6 +525,10 @@ class ObjectHydrator extends AbstractHydrator
$resultKey = $index; $resultKey = $index;
} }
} }
if (isset($this->_hints[Query::HINT_INTERNAL_ITERATION]) && $this->_hints[Query::HINT_INTERNAL_ITERATION]) {
$this->_uow->hydrationComplete();
}
} }
if ( ! isset($resultKey) ) { if ( ! isset($resultKey) ) {

View File

@ -144,5 +144,9 @@ class SimpleObjectHydrator extends AbstractHydrator
$entity = $uow->createEntity($entityName, $data, $this->_hints); $entity = $uow->createEntity($entityName, $data, $this->_hints);
$result[] = $entity; $result[] = $entity;
if (isset($this->_hints[Query::HINT_INTERNAL_ITERATION]) && $this->_hints[Query::HINT_INTERNAL_ITERATION]) {
$this->_uow->hydrationComplete();
}
} }
} }

View File

@ -2,6 +2,7 @@
namespace Doctrine\Tests\ORM\Functional; namespace Doctrine\Tests\ORM\Functional;
use Doctrine\ORM\Event\PreUpdateEventArgs; use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Query;
class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase
{ {
@ -150,6 +151,116 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertTrue($e2->prePersistCallbackInvoked); $this->assertTrue($e2->prePersistCallbackInvoked);
} }
/**
* @group DDC-54
* @group DDC-3005
*/
public function testCascadedEntitiesLoadedInPostLoad()
{
$e1 = new LifecycleCallbackTestEntity();
$e2 = new LifecycleCallbackTestEntity();
$c = new LifecycleCallbackCascader();
$this->_em->persist($c);
$c->entities[] = $e1;
$c->entities[] = $e2;
$e1->cascader = $c;
$e2->cascader = $c;
$this->_em->flush();
$this->_em->clear();
$dql = <<<'DQL'
SELECT
e, c
FROM
Doctrine\Tests\ORM\Functional\LifecycleCallbackTestEntity AS e
LEFT JOIN
e.cascader AS c
WHERE
e.id IN (%s, %s)
DQL;
$entities = $this
->_em
->createQuery(sprintf($dql, $e1->getId(), $e2->getId()))
->getResult();
$this->assertTrue(current($entities)->postLoadCallbackInvoked);
$this->assertTrue(current($entities)->postLoadCascaderNotNull);
$this->assertTrue(current($entities)->cascader->postLoadCallbackInvoked);
$this->assertEquals(current($entities)->cascader->postLoadEntitiesCount, 2);
}
/**
* @group DDC-54
* @group DDC-3005
*/
public function testCascadedEntitiesNotLoadedInPostLoadDuringIteration()
{
$e1 = new LifecycleCallbackTestEntity();
$e2 = new LifecycleCallbackTestEntity();
$c = new LifecycleCallbackCascader();
$this->_em->persist($c);
$c->entities[] = $e1;
$c->entities[] = $e2;
$e1->cascader = $c;
$e2->cascader = $c;
$this->_em->flush();
$this->_em->clear();
$dql = <<<'DQL'
SELECT
e, c
FROM
Doctrine\Tests\ORM\Functional\LifecycleCallbackTestEntity AS e
LEFT JOIN
e.cascader AS c
WHERE
e.id IN (%s, %s)
DQL;
$result = $this
->_em
->createQuery(sprintf($dql, $e1->getId(), $e2->getId()))
->iterate();
foreach ($result as $entity) {
$this->assertTrue($entity[0]->postLoadCallbackInvoked);
$this->assertFalse($entity[0]->postLoadCascaderNotNull);
break;
}
}
/**
* @group DDC-54
* @group DDC-3005
*/
public function testCascadedEntitiesNotLoadedInPostLoadDuringIterationWithSimpleObjectHydrator()
{
$this->_em->persist(new LifecycleCallbackTestEntity());
$this->_em->persist(new LifecycleCallbackTestEntity());
$this->_em->flush();
$this->_em->clear();
$result = $this
->_em
->createQuery('SELECT e FROM Doctrine\Tests\ORM\Functional\LifecycleCallbackTestEntity AS e')
->iterate(null, Query::HYDRATE_SIMPLEOBJECT);
foreach ($result as $entity) {
$this->assertTrue($entity[0]->postLoadCallbackInvoked);
$this->assertFalse($entity[0]->postLoadCascaderNotNull);
break;
}
}
public function testLifecycleCallbacksGetInherited() public function testLifecycleCallbacksGetInherited()
{ {
$childMeta = $this->_em->getClassMetadata(__NAMESPACE__ . '\LifecycleCallbackChildEntity'); $childMeta = $this->_em->getClassMetadata(__NAMESPACE__ . '\LifecycleCallbackChildEntity');
@ -282,7 +393,7 @@ class LifecycleCallbackTestEntity
public $prePersistCallbackInvoked = false; public $prePersistCallbackInvoked = false;
public $postPersistCallbackInvoked = false; public $postPersistCallbackInvoked = false;
public $postLoadCallbackInvoked = false; public $postLoadCallbackInvoked = false;
public $postLoadCascaderNotNull = false;
public $preFlushCallbackInvoked = false; public $preFlushCallbackInvoked = false;
/** /**
@ -322,6 +433,7 @@ class LifecycleCallbackTestEntity
/** @PostLoad */ /** @PostLoad */
public function doStuffOnPostLoad() { public function doStuffOnPostLoad() {
$this->postLoadCallbackInvoked = true; $this->postLoadCallbackInvoked = true;
$this->postLoadCascaderNotNull = isset($this->cascader);
} }
/** @PreUpdate */ /** @PreUpdate */
@ -336,11 +448,15 @@ class LifecycleCallbackTestEntity
} }
/** /**
* @Entity * @Entity @HasLifecycleCallbacks
* @Table(name="lc_cb_test_cascade") * @Table(name="lc_cb_test_cascade")
*/ */
class LifecycleCallbackCascader class LifecycleCallbackCascader
{ {
/* test stuff */
public $postLoadCallbackInvoked = false;
public $postLoadEntitiesCount = 0;
/** /**
* @Id @Column(type="integer") * @Id @Column(type="integer")
* @GeneratedValue(strategy="AUTO") * @GeneratedValue(strategy="AUTO")
@ -356,6 +472,12 @@ class LifecycleCallbackCascader
{ {
$this->entities = new \Doctrine\Common\Collections\ArrayCollection(); $this->entities = new \Doctrine\Common\Collections\ArrayCollection();
} }
/** @PostLoad */
public function doStuffOnPostLoad() {
$this->postLoadCallbackInvoked = true;
$this->postLoadEntitiesCount = count($this->entities);
}
} }
/** @MappedSuperclass @HasLifecycleCallbacks */ /** @MappedSuperclass @HasLifecycleCallbacks */