diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index 97c3f8508..460bf12a0 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -456,7 +456,7 @@ abstract class AbstractQuery */ public function iterate(array $params = array(), $hydrationMode = self::HYDRATE_OBJECT) { - return $this->_em->getHydrator($this->_hydrationMode)->iterate( + return $this->_em->newHydrator($this->_hydrationMode)->iterate( $this->_doExecute($params, $hydrationMode), $this->_resultSetMapping ); } diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index 7cee113de..f3d3eae06 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -510,31 +510,47 @@ class EntityManager /** * Gets a hydrator for the given hydration mode. * - * @param $hydrationMode + * This method caches the hydrator instances which is used for all queries that don't + * selectively iterate over the result. + * + * @param int $hydrationMode + * @return Doctrine\ORM\Internal\Hydration\AbstractHydrator */ public function getHydrator($hydrationMode) { if ( ! isset($this->_hydrators[$hydrationMode])) { - switch ($hydrationMode) { - case Query::HYDRATE_OBJECT: - $this->_hydrators[$hydrationMode] = new Internal\Hydration\ObjectHydrator($this); - break; - case Query::HYDRATE_ARRAY: - $this->_hydrators[$hydrationMode] = new Internal\Hydration\ArrayHydrator($this); - break; - case Query::HYDRATE_SCALAR: - $this->_hydrators[$hydrationMode] = new Internal\Hydration\ScalarHydrator($this); - break; - case Query::HYDRATE_SINGLE_SCALAR: - $this->_hydrators[$hydrationMode] = new Internal\Hydration\SingleScalarHydrator($this); - break; - default: - throw ORMException::invalidHydrationMode($hydrationMode); - } + $this->_hydrators[$hydrationMode] = $this->newHydrator($hydrationMode); } return $this->_hydrators[$hydrationMode]; } + /** + * Create a new instance for the given hydration mode. + * + * @param int $hydrationMode + * @return Doctrine\ORM\Internal\Hydration\AbstractHydrator + */ + public function newHydrator($hydrationMode) + { + switch ($hydrationMode) { + case Query::HYDRATE_OBJECT: + $hydrator = new Internal\Hydration\ObjectHydrator($this); + break; + case Query::HYDRATE_ARRAY: + $hydrator = new Internal\Hydration\ArrayHydrator($this); + break; + case Query::HYDRATE_SCALAR: + $hydrator = new Internal\Hydration\ScalarHydrator($this); + break; + case Query::HYDRATE_SINGLE_SCALAR: + $hydrator = new Internal\Hydration\SingleScalarHydrator($this); + break; + default: + throw ORMException::invalidHydrationMode($hydrationMode); + } + return $hydrator; + } + /** * Gets the proxy factory used by the EntityManager to create entity proxies. * diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC309Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC309Test.php new file mode 100644 index 000000000..728e11d25 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC309Test.php @@ -0,0 +1,73 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC309Country'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC309User'), + )); + } + + public function testTwoIterateHydrations() + { + $c1 = new DDC309Country(); + $c2 = new DDC309Country(); + $u1 = new DDC309User(); + $u2 = new DDC309User(); + + $this->_em->persist($c1); + $this->_em->persist($c2); + $this->_em->persist($u1); + $this->_em->persist($u2); + $this->_em->flush(); + $this->_em->clear(); + + $q = $this->_em->createQuery('SELECT c FROM Doctrine\Tests\ORM\Functional\Ticket\DDC309Country c')->iterate(); + $c = $q->next(); + + $this->assertEquals(1, $c[0]->id); + + $r = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\ORM\Functional\Ticket\DDC309User u')->iterate(); + $u = $r->next(); // This line breaks + + $this->assertEquals(1, $u[0]->id); + + $c = $q->next(); + $u = $r->next(); + + $this->assertEquals(2, $c[0]->id); + $this->assertEquals(2, $u[0]->id); + } +} + +/** + * @Entity + */ +class DDC309Country +{ + /** + * @Id + * @Column(name="id", type="integer") + * @GeneratedValue(strategy="AUTO") + */ + public $id; +} + +/** + * @Entity + */ +class DDC309User +{ + /** + * @Id + * @Column(name="id", type="integer") + * @GeneratedValue(strategy="AUTO") + */ + public $id; +}