1
0
mirror of synced 2025-02-20 22:23:14 +03:00

Updated tests.

This commit is contained in:
Roman S. Borschel 2010-07-29 14:08:36 +02:00
parent e69c7c7c60
commit 954a8c3935
3 changed files with 117 additions and 59 deletions

View File

@ -1344,34 +1344,51 @@ class UnitOfWork implements PropertyChangedListener
*/
private function doMerge($entity, array &$visited, $prevManagedCopy = null, $assoc = null)
{
$class = $this->em->getClassMetadata(get_class($entity));
$id = $class->getIdentifierValues($entity);
if ( ! $id) {
throw new InvalidArgumentException('New entity detected during merge.'
. ' Persist the new entity before merging.');
$oid = spl_object_hash($entity);
if (isset($visited[$oid])) {
return; // Prevent infinite recursion
}
// MANAGED entities are ignored by the merge operation
$class = $this->em->getClassMetadata(get_class($entity));
// First we assume DETACHED, although it can still be NEW but we can avoid
// an extra db-roundtrip this way. If it is DETACHED or NEW, we need to fetch
// it from the db anyway in order to merge.
// MANAGED entities are ignored by the merge operation.
if ($this->getEntityState($entity, self::STATE_DETACHED) == self::STATE_MANAGED) {
$managedCopy = $entity;
} else {
// Try to look the entity up in the identity map.
$managedCopy = $this->tryGetById($id, $class->rootEntityName);
if ($managedCopy) {
// We have the entity in-memory already, just make sure its not removed.
if ($this->getEntityState($managedCopy) == self::STATE_REMOVED) {
throw new InvalidArgumentException('Removed entity detected during merge.'
. ' Can not merge with a removed entity.');
}
} else {
// We need to fetch the managed copy in order to merge.
$managedCopy = $this->em->find($class->name, $id);
}
$id = $class->getIdentifierValues($entity);
if ($managedCopy === null) {
throw new InvalidArgumentException('New entity detected during merge.'
. ' Persist the new entity before merging.');
// If there is no ID, it is actually NEW.
if ( ! $id) {
$managedCopy = $class->newInstance();
$this->persistNew($class, $managedCopy);
} else {
$managedCopy = $this->tryGetById($id, $class->rootEntityName);
if ($managedCopy) {
// We have the entity in-memory already, just make sure its not removed.
if ($this->getEntityState($managedCopy) == self::STATE_REMOVED) {
throw new InvalidArgumentException('Removed entity detected during merge.'
. ' Can not merge with a removed entity.');
}
} else {
// We need to fetch the managed copy in order to merge.
$managedCopy = $this->em->find($class->name, $id);
}
if ($managedCopy === null) {
// If the identifier is ASSIGNED, it is NEW, otherwise an error
// since the managed entity was not found.
if ($class->isIdentifierNatural()) {
$managedCopy = $class->newInstance();
$class->setIdentifierValues($managedCopy, $id);
$this->persistNew($class, $managedCopy);
} else {
throw new EntityNotFoundException;
}
}
}
if ($class->isVersioned) {
@ -1388,17 +1405,20 @@ class UnitOfWork implements PropertyChangedListener
if ( ! isset($class->associationMappings[$name])) {
$prop->setValue($managedCopy, $prop->getValue($entity));
} else {
// why $assoc2? See the method signature, there is $assoc already!
$assoc2 = $class->associationMappings[$name];
if ($assoc2->isOneToOne()) {
if ( ! $assoc2->isCascadeMerge) {
$other = $class->reflFields[$name]->getValue($entity); //TODO: Just $prop->getValue($entity)?
$other = $prop->getValue($entity);
if ($other !== null) {
$targetClass = $this->em->getClassMetadata($assoc2->targetEntityName);
$id = $targetClass->getIdentifierValues($other);
$proxy = $this->em->getProxyFactory()->getProxy($assoc2->targetEntityName, $id);
$prop->setValue($managedCopy, $proxy);
$this->registerManaged($proxy, $id, array());
if ($this->getEntityState($other, self::STATE_DETACHED) == self::STATE_MANAGED) {
$prop->setValue($managedCopy, $other);
} else {
$targetClass = $this->em->getClassMetadata($assoc2->targetEntityName);
$id = $targetClass->getIdentifierValues($other);
$proxy = $this->em->getProxyFactory()->getProxy($assoc2->targetEntityName, $id);
$prop->setValue($managedCopy, $proxy);
$this->registerManaged($proxy, $id, array());
}
}
}
} else {
@ -1421,8 +1441,8 @@ class UnitOfWork implements PropertyChangedListener
//TODO: put changed fields in changeset...?
}
}
if ($class->isChangeTrackingDeferredExplicit()) {
//TODO: Mark $managedCopy for dirty check...? ($this->scheduledForDirtyCheck)
if ( ! $class->isChangeTrackingDeferredImplicit()) {
$this->scheduleForDirtyCheck($entity);
}
}

View File

@ -768,37 +768,39 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals('Stephan', $this->_em->find(get_class($user), $userId)->name);
}
//DRAFT OF EXPECTED/DESIRED BEHAVIOR
/*public function testPersistentCollectionContainsDoesNeverInitialize()
public function testMergePersistsNewEntities()
{
$user = new CmsUser;
$user->name = 'Guilherme';
$user->username = 'gblanco';
$user->status = 'developer';
$group = new CmsGroup;
$group->name = 'Developers';
$user->addGroup($group);
$this->_em->persist($user);
$user = new CmsUser();
$user->username = "beberlei";
$user->name = "Benjamin E.";
$user->status = 'active';
$managedUser = $this->_em->merge($user);
$this->assertEquals('beberlei', $managedUser->username);
$this->assertEquals('Benjamin E.', $managedUser->name);
$this->assertEquals('active', $managedUser->status);
$this->assertTrue($user !== $managedUser);
$this->assertTrue($this->_em->contains($managedUser));
$this->_em->flush();
$userId = $managedUser->id;
$this->_em->clear();
$group = $this->_em->find(get_class($group), $group->getId());
$user2 = new CmsUser;
$user2->id = $user->getId();
$this->assertFalse($group->getUsers()->contains($user2));
$this->assertFalse($group->getUsers()->isInitialized());
$user2 = $this->_em->getReference(get_class($user), $user->getId());
$this->assertTrue($group->getUsers()->contains($user2));
$this->assertFalse($group->getUsers()->isInitialized());
$this->assertTrue($this->_em->find(get_class($managedUser), $userId) instanceof CmsUser);
}
public function testMergeThrowsExceptionIfEntityWithGeneratedIdentifierDoesNotExist()
{
$user = new CmsUser();
$user->username = "beberlei";
$user->name = "Benjamin E.";
$user->status = 'active';
$user->id = 42;
try {
$this->_em->merge($user);
$this->fail();
} catch (\Doctrine\ORM\EntityNotFoundException $enfe) {}
}
*/
}

View File

@ -0,0 +1,36 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
require_once __DIR__ . '/../../../TestInit.php';
class DDC518Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
public function testMergeWithRelatedNew()
{
$article = new \Doctrine\Tests\Models\CMS\CmsArticle();
$article->text = "foo";
$article->topic = "bar";
$this->_em->persist($article);
$this->_em->flush();
$this->_em->detach($article);
$this->_em->clear();
$user = new \Doctrine\Tests\Models\CMS\CmsUser();
$user->username = "beberlei";
$user->name = "Benjamin Eberlei";
$user->status = "active";
$article->user = $user;
$this->_em->persist($user);
$managedArticle = $this->_em->merge($article);
$this->assertSame($article->user, $managedArticle->user);
}
}