From 82e42123de5568edc67c144ffaf1e6255ec6537d Mon Sep 17 00:00:00 2001 From: romanb Date: Tue, 23 Feb 2010 14:58:12 +0000 Subject: [PATCH] [2.0][DDC-345] Fixed. --- lib/Doctrine/ORM/Query.php | 3 +- lib/Doctrine/ORM/UnitOfWork.php | 2 +- .../ORM/Functional/BasicFunctionalTest.php | 12 +- .../ORM/Functional/Ticket/DDC345Test.php | 157 ++++++++++++++++++ 4 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php diff --git a/lib/Doctrine/ORM/Query.php b/lib/Doctrine/ORM/Query.php index f51b1fadc..b71842e69 100644 --- a/lib/Doctrine/ORM/Query.php +++ b/lib/Doctrine/ORM/Query.php @@ -219,7 +219,8 @@ final class Query extends AbstractQuery } if (is_object($value)) { - $values = $this->_em->getClassMetadata(get_class($value))->getIdentifierValues($value); + //$values = $this->_em->getClassMetadata(get_class($value))->getIdentifierValues($value); + $values = $this->_em->getUnitOfWork()->getEntityIdentifier($value); //var_dump($this->_em->getUnitOfWork()->getEntityIdentifier($value)); $sqlPositions = $paramMappings[$key]; $sqlParams = array_merge($sqlParams, array_combine((array)$sqlPositions, $values)); diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 2f16ddba2..21b39c60b 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -607,7 +607,6 @@ class UnitOfWork implements PropertyChangedListener $idGen = $targetClass->idGenerator; if ( ! $idGen->isPostInsertGenerator()) { $idValue = $idGen->generate($this->_em, $entry); - $this->_entityStates[$oid] = self::STATE_MANAGED; if ( ! $idGen instanceof \Doctrine\ORM\Id\Assigned) { $this->_entityIdentifiers[$oid] = array($targetClass->identifier[0] => $idValue); $targetClass->getSingleIdReflectionProperty()->setValue($entry, $idValue); @@ -616,6 +615,7 @@ class UnitOfWork implements PropertyChangedListener } $this->addToIdentityMap($entry); } + $this->_entityStates[$oid] = self::STATE_MANAGED; // NEW entities are INSERTed within the current unit of work. $this->_entityInsertions[$oid] = $entry; diff --git a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php index 0b7c5ac69..116c8a14f 100644 --- a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php @@ -615,7 +615,7 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase /** * @group ref */ - /*public function testQueryEntityByReference() + public function testQueryEntityByReference() { $user = new CmsUser; $user->name = 'Guilherme'; @@ -633,13 +633,21 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->flush(); $this->_em->clear(); + //$this->_em->getConnection()->getConfiguration()->setSqlLogger(new \Doctrine\DBAL\Logging\EchoSqlLogger); + $userRef = $this->_em->getReference('Doctrine\Tests\Models\CMS\CmsUser', $user->getId()); $address2 = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsAddress a where a.user = :user') ->setParameter('user', $userRef) ->getSingleResult(); + $this->assertTrue($address2->getUser() instanceof \Doctrine\ORM\Proxy\Proxy); + $this->assertTrue($userRef === $address2->getUser()); + $this->assertFalse($userRef->__isInitialized__); + $this->assertEquals('Germany', $address2->country); + $this->assertEquals('Berlin', $address2->city); + $this->assertEquals('12345', $address2->zip); - }*/ + } //DRAFT OF EXPECTED/DESIRED BEHAVIOR /*public function testPersistentCollectionContainsDoesNeverInitialize() diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php new file mode 100644 index 000000000..92a984525 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php @@ -0,0 +1,157 @@ +_em->getConnection()->getConfiguration()->setSqlLogger(new \Doctrine\DBAL\Logging\EchoSqlLogger); + $this->_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC345User'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC345Group'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC345Membership'), + )); + } + + public function testTwoIterateHydrations() + { + // Create User + $user = new DDC345User; + $user->name = 'Test User'; + $this->_em->persist($user); // $em->flush() does not change much here + + // Create Group + $group = new DDC345Group; + $group->name = 'Test Group'; + $this->_em->persist($group); // $em->flush() does not change much here + + $membership = new DDC345Membership; + $membership->group = $group; + $membership->user = $user; + $membership->state = 'active'; + + //$this->_em->persist($membership); // COMMENT OUT TO SEE BUG + /* + This should be not necessary, but without, its PrePersist is called twice, + $membership seems to be persisted twice, but all properties but the + ones set by LifecycleCallbacks are deleted. + */ + + $user->Memberships->add($membership); + $group->Memberships->add($membership); + + $this->_em->flush(); + + $this->assertEquals(1, $membership->prePersistCallCount); + $this->assertEquals(0, $membership->preUpdateCallCount); + $this->assertTrue($membership->updated instanceof \DateTime); + } +} + +/** + * @Entity + */ +class DDC345User +{ + /** + * @Id + * @Column(type="integer") + * @GeneratedValue + */ + public $id; + + /** @Column(type="string") */ + public $name; + + /** @OneToMany(targetEntity="DDC345Membership", mappedBy="user", cascade={"persist"}) */ + public $Memberships; + + public function __construct() + { + $this->Memberships = new \Doctrine\Common\Collections\ArrayCollection; + } +} + +/** + * @Entity + */ +class DDC345Group +{ + /** + * @Id + * @Column(type="integer") + * @GeneratedValue + */ + public $id; + + /** @Column(type="string") */ + public $name; + + /** @OneToMany(targetEntity="DDC345Membership", mappedBy="group", cascade={"persist"}) */ + public $Memberships; + + + public function __construct() + { + $this->Memberships = new \Doctrine\Common\Collections\ArrayCollection; + } +} + +/** + * @Entity + * @HasLifecycleCallbacks + * @Table(name="ddc345_memberships", uniqueConstraints={ + * @UniqueConstraint(name="ddc345_memship_fks", columns={"user_id","group_id"}) + * }) + */ +class DDC345Membership +{ + /** + * @Id + * @Column(type="integer") + * @GeneratedValue + */ + public $id; + + /** + * @OneToOne(targetEntity="DDC345User") + * @JoinColumn(name="user_id", referencedColumnName="id", nullable=false) + */ + public $user; + + /** + * @OneToOne(targetEntity="DDC345Group") + * @JoinColumn(name="group_id", referencedColumnName="id", nullable=false) + */ + public $group; + + /** @Column(type="string") */ + public $state; + + /** @Column(type="datetime") */ + public $updated; + + public $prePersistCallCount = 0; + public $preUpdateCallCount = 0; + + /** @PrePersist */ + public function doStuffOnPrePersist() + { + //echo "***** PrePersist\n"; + ++$this->prePersistCallCount; + $this->updated = new \DateTime; + } + + /** @PreUpdate */ + public function doStuffOnPreUpdate() + { + //echo "***** PreUpdate\n"; + ++$this->preUpdateCallCount; + $this->updated = new \DateTime; + } +} +