1
0
mirror of synced 2025-01-27 18:41:46 +03:00

[DDC-167] Implemented.

This commit is contained in:
Roman S. Borschel 2010-07-20 14:20:13 +02:00
parent 2c28872af8
commit 913e58e385
5 changed files with 77 additions and 13 deletions

View File

@ -330,12 +330,10 @@ class EntityManager
/** /**
* Gets a reference to the entity identified by the given type and identifier * Gets a reference to the entity identified by the given type and identifier
* without actually loading it. * without actually loading it, if the entity is not yet loaded.
*
* If partial objects are allowed, this method will return a partial object that only
* has its identifier populated. Otherwise a proxy is returned that automatically
* loads itself on first access.
* *
* @param string $entityName The name of the entity type.
* @param mixed $identifier The entity identifier.
* @return object The entity reference. * @return object The entity reference.
*/ */
public function getReference($entityName, $identifier) public function getReference($entityName, $identifier)
@ -355,6 +353,44 @@ class EntityManager
return $entity; return $entity;
} }
/**
* Gets a partial reference to the entity identified by the given type and identifier
* without actually loading it, if the entity is not yet loaded.
*
* The returned reference may be a partial object if the entity is not yet loaded/managed.
* If it is a partial object it will not initialize the rest of the entity state on access.
* Thus you can only ever safely access the identifier of an entity obtained through
* this method.
*
* The use-cases for partial references involve maintaining bidirectional associations
* without loading one side of the association or to update an entity without loading it.
* Note, however, that in the latter case the original (persistent) entity data will
* never be visible to the application (especially not event listeners) as it will
* never be loaded in the first place.
*
* @param string $entityName The name of the entity type.
* @param mixed $identifier The entity identifier.
* @return object The (partial) entity reference.
*/
public function getPartialReference($entityName, $identifier)
{
$class = $this->metadataFactory->getMetadataFor($entityName);
// Check identity map first, if its already in there just return it.
if ($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) {
return $entity;
}
if ( ! is_array($identifier)) {
$identifier = array($class->identifier[0] => $identifier);
}
$entity = $class->newInstance();
$class->setIdentifierValues($entity, $identifier);
$this->unitOfWork->registerManaged($entity, $identifier, array());
return $entity;
}
/** /**
* Clears the EntityManager. All entities that are currently managed * Clears the EntityManager. All entities that are currently managed
* by this EntityManager become detached. * by this EntityManager become detached.

View File

@ -158,14 +158,10 @@ class ClassMetadata extends ClassMetadataInfo
* @param mixed $id * @param mixed $id
* @todo Rename to assignIdentifier() * @todo Rename to assignIdentifier()
*/ */
public function setIdentifierValues($entity, $id) public function setIdentifierValues($entity, array $id)
{ {
if ($this->isIdentifierComposite) { foreach ($id as $idField => $idValue) {
foreach ($id as $idField => $idValue) { $this->reflFields[$idField]->setValue($entity, $idValue);
$this->reflFields[$idField]->setValue($entity, $idValue);
}
} else {
$this->reflFields[$this->identifier[0]]->setValue($entity, $id);
} }
} }

View File

@ -76,6 +76,14 @@ class EntityManagerTest extends \Doctrine\Tests\OrmTestCase
$this->assertType('\Doctrine\ORM\Query', $this->_em->createQuery()); $this->assertType('\Doctrine\ORM\Query', $this->_em->createQuery());
} }
public function testGetPartialReference()
{
$user = $this->_em->getPartialReference('Doctrine\Tests\Models\CMS\CmsUser', 42);
$this->assertTrue($this->_em->contains($user));
$this->assertEquals(42, $user->id);
$this->assertNull($user->getName());
}
public function testCreateQuery() public function testCreateQuery()
{ {
$q = $this->_em->createQuery('SELECT 1'); $q = $this->_em->createQuery('SELECT 1');

View File

@ -744,6 +744,30 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(0, $this->_em->getConnection()->fetchColumn("select count(*) from cms_users_groups")); $this->assertEquals(0, $this->_em->getConnection()->fetchColumn("select count(*) from cms_users_groups"));
} }
public function testGetPartialReferenceToUpdateObjectWithoutLoadingIt()
{
//$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
$user = new CmsUser();
$user->username = "beberlei";
$user->name = "Benjamin E.";
$user->status = 'active';
$this->_em->persist($user);
$this->_em->flush();
$userId = $user->id;
$this->_em->clear();
$user = $this->_em->getPartialReference('Doctrine\Tests\Models\CMS\CmsUser', $userId);
$this->assertTrue($this->_em->contains($user));
$this->assertNull($user->getName());
$this->assertEquals($userId, $user->id);
$user->name = 'Stephan';
$this->_em->flush();
$this->_em->clear();
$this->assertEquals('Stephan', $this->_em->find(get_class($user), $userId)->name);
}
//DRAFT OF EXPECTED/DESIRED BEHAVIOR //DRAFT OF EXPECTED/DESIRED BEHAVIOR
/*public function testPersistentCollectionContainsDoesNeverInitialize() /*public function testPersistentCollectionContainsDoesNeverInitialize()

View File

@ -387,7 +387,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
// Tough one: Many-many self-referencing ("friends") with class table inheritance // Tough one: Many-many self-referencing ("friends") with class table inheritance
$q3 = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends'); $q3 = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends');
$person = new \Doctrine\Tests\Models\Company\CompanyPerson; $person = new \Doctrine\Tests\Models\Company\CompanyPerson;
$this->_em->getClassMetadata(get_class($person))->setIdentifierValues($person, 101); $this->_em->getClassMetadata(get_class($person))->setIdentifierValues($person, array('id' => 101));
$q3->setParameter('param', $person); $q3->setParameter('param', $person);
$this->assertEquals( $this->assertEquals(
'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c1_.car_id AS car_id3, c2_.salary AS salary4, c2_.department AS department5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id = ?)', 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c1_.car_id AS car_id3, c2_.salary AS salary4, c2_.department AS department5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id = ?)',