[2.0][DDC-32] Fixed.
This commit is contained in:
parent
e1645efa76
commit
b8bcd51ff2
@ -312,12 +312,19 @@ class EntityManager
|
|||||||
*/
|
*/
|
||||||
public function getReference($entityName, $identifier)
|
public function getReference($entityName, $identifier)
|
||||||
{
|
{
|
||||||
|
// Check identity map first, if its already in there just return it.
|
||||||
|
if ($entity = $this->_unitOfWork->tryGetById($identifier,
|
||||||
|
$this->_metadataFactory->getMetadataFor($entityName)->rootEntityName)) {
|
||||||
|
return $entity;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->_config->getAllowPartialObjects()) {
|
if ($this->_config->getAllowPartialObjects()) {
|
||||||
$entity = new $entityName;
|
$entity = new $entityName;
|
||||||
$this->getClassMetadata($entityName)->setEntityIdentifier($entity, $identifier);
|
$this->getClassMetadata($entityName)->setIdentifierValues($entity, $identifier);
|
||||||
} else {
|
} else {
|
||||||
$entity = $this->_proxyFactory->getReferenceProxy($entityName, $identifier);
|
$entity = $this->_proxyFactory->getReferenceProxy($entityName, $identifier);
|
||||||
}
|
}
|
||||||
|
$this->_unitOfWork->registerManaged($entity, (array) $identifier, array());
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ namespace Doctrine\ORM;
|
|||||||
use Doctrine\Common\Collections\ArrayCollection,
|
use Doctrine\Common\Collections\ArrayCollection,
|
||||||
Doctrine\Common\Collections\Collection,
|
Doctrine\Common\Collections\Collection,
|
||||||
Doctrine\Common\DoctrineException,
|
Doctrine\Common\DoctrineException,
|
||||||
|
Doctrine\Common\NotifyPropertyChanged,
|
||||||
Doctrine\Common\PropertyChangedListener,
|
Doctrine\Common\PropertyChangedListener,
|
||||||
Doctrine\ORM\Event\LifecycleEventArgs;
|
Doctrine\ORM\Event\LifecycleEventArgs;
|
||||||
|
|
||||||
@ -239,11 +240,19 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* Commits the UnitOfWork, executing all operations that have been postponed
|
* Commits the UnitOfWork, executing all operations that have been postponed
|
||||||
* up to this point. The state of all managed entities will be synchronized with
|
* up to this point. The state of all managed entities will be synchronized with
|
||||||
* the database.
|
* the database.
|
||||||
|
*
|
||||||
|
* The operations are executed in the following order:
|
||||||
|
*
|
||||||
|
* 1) All entity insertions
|
||||||
|
* 2) All entity updates
|
||||||
|
* 3) All collection deletions
|
||||||
|
* 4) All collection updates
|
||||||
|
* 5) All entity deletions
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public function commit()
|
public function commit()
|
||||||
{
|
{
|
||||||
// Compute changes done since last commit.
|
// Compute changes done since last commit.
|
||||||
// This populates _entityUpdates and _collectionUpdates.
|
|
||||||
$this->computeChangeSets();
|
$this->computeChangeSets();
|
||||||
|
|
||||||
if ( ! ($this->_entityInsertions ||
|
if ( ! ($this->_entityInsertions ||
|
||||||
@ -879,6 +888,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* Schedules an extra update that will be executed immediately after the
|
* Schedules an extra update that will be executed immediately after the
|
||||||
* regular entity updates within the currently running commit cycle.
|
* regular entity updates within the currently running commit cycle.
|
||||||
*
|
*
|
||||||
|
* @ignore
|
||||||
* @param $entity
|
* @param $entity
|
||||||
* @param $changeset
|
* @param $changeset
|
||||||
*/
|
*/
|
||||||
@ -959,6 +969,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* Note that entities in a hierarchy are registered with the class name of
|
* Note that entities in a hierarchy are registered with the class name of
|
||||||
* the root entity.
|
* the root entity.
|
||||||
*
|
*
|
||||||
|
* @ignore
|
||||||
* @param object $entity The entity to register.
|
* @param object $entity The entity to register.
|
||||||
* @return boolean TRUE if the registration was successful, FALSE if the identity of
|
* @return boolean TRUE if the registration was successful, FALSE if the identity of
|
||||||
* the entity in question is already managed.
|
* the entity in question is already managed.
|
||||||
@ -968,14 +979,14 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
$classMetadata = $this->_em->getClassMetadata(get_class($entity));
|
$classMetadata = $this->_em->getClassMetadata(get_class($entity));
|
||||||
$idHash = implode(' ', $this->_entityIdentifiers[spl_object_hash($entity)]);
|
$idHash = implode(' ', $this->_entityIdentifiers[spl_object_hash($entity)]);
|
||||||
if ($idHash === '') {
|
if ($idHash === '') {
|
||||||
throw DoctrineException::entityMustHaveIdentifyToBeAddedToIdentityMap($entity);
|
throw DoctrineException::entityMustHaveIdentityToBeAddedToIdentityMap($entity);
|
||||||
}
|
}
|
||||||
$className = $classMetadata->rootEntityName;
|
$className = $classMetadata->rootEntityName;
|
||||||
if (isset($this->_identityMap[$className][$idHash])) {
|
if (isset($this->_identityMap[$className][$idHash])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$this->_identityMap[$className][$idHash] = $entity;
|
$this->_identityMap[$className][$idHash] = $entity;
|
||||||
if ($entity instanceof \Doctrine\Common\NotifyPropertyChanged) {
|
if ($entity instanceof NotifyPropertyChanged) {
|
||||||
$entity->addPropertyChangedListener($this);
|
$entity->addPropertyChangedListener($this);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1021,6 +1032,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* Removes an entity from the identity map. This effectively detaches the
|
* Removes an entity from the identity map. This effectively detaches the
|
||||||
* entity from the persistence management of Doctrine.
|
* entity from the persistence management of Doctrine.
|
||||||
*
|
*
|
||||||
|
* @ignore
|
||||||
* @param object $entity
|
* @param object $entity
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
@ -1046,6 +1058,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* INTERNAL:
|
* INTERNAL:
|
||||||
* Gets an entity in the identity map by its identifier hash.
|
* Gets an entity in the identity map by its identifier hash.
|
||||||
*
|
*
|
||||||
|
* @ignore
|
||||||
* @param string $idHash
|
* @param string $idHash
|
||||||
* @param string $rootClassName
|
* @param string $rootClassName
|
||||||
* @return object
|
* @return object
|
||||||
@ -1060,6 +1073,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* Tries to get an entity by its identifier hash. If no entity is found for
|
* Tries to get an entity by its identifier hash. If no entity is found for
|
||||||
* the given hash, FALSE is returned.
|
* the given hash, FALSE is returned.
|
||||||
*
|
*
|
||||||
|
* @ignore
|
||||||
* @param string $idHash
|
* @param string $idHash
|
||||||
* @param string $rootClassName
|
* @param string $rootClassName
|
||||||
* @return mixed The found entity or FALSE.
|
* @return mixed The found entity or FALSE.
|
||||||
@ -1097,6 +1111,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* INTERNAL:
|
* INTERNAL:
|
||||||
* Checks whether an identifier hash exists in the identity map.
|
* Checks whether an identifier hash exists in the identity map.
|
||||||
*
|
*
|
||||||
|
* @ignore
|
||||||
* @param string $idHash
|
* @param string $idHash
|
||||||
* @param string $rootClassName
|
* @param string $rootClassName
|
||||||
* @return boolean
|
* @return boolean
|
||||||
@ -1597,6 +1612,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* invoked on that entity at the beginning of the next commit of this
|
* invoked on that entity at the beginning of the next commit of this
|
||||||
* UnitOfWork.
|
* UnitOfWork.
|
||||||
*
|
*
|
||||||
|
* @ignore
|
||||||
* @param object $entity
|
* @param object $entity
|
||||||
*/
|
*/
|
||||||
public function scheduleOrphanRemoval($entity)
|
public function scheduleOrphanRemoval($entity)
|
||||||
@ -1636,6 +1652,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* INTERNAL:
|
* INTERNAL:
|
||||||
* Creates an entity. Used for reconstitution of entities during hydration.
|
* Creates an entity. Used for reconstitution of entities during hydration.
|
||||||
*
|
*
|
||||||
|
* @ignore
|
||||||
* @param string $className The name of the entity class.
|
* @param string $className The name of the entity class.
|
||||||
* @param array $data The data for the entity.
|
* @param array $data The data for the entity.
|
||||||
* @return object The created entity instance.
|
* @return object The created entity instance.
|
||||||
@ -1668,7 +1685,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
$this->_entityStates[$oid] = self::STATE_MANAGED;
|
$this->_entityStates[$oid] = self::STATE_MANAGED;
|
||||||
$this->_originalEntityData[$oid] = $data;
|
$this->_originalEntityData[$oid] = $data;
|
||||||
$this->_identityMap[$class->rootEntityName][$idHash] = $entity;
|
$this->_identityMap[$class->rootEntityName][$idHash] = $entity;
|
||||||
if ($entity instanceof \Doctrine\Common\NotifyPropertyChanged) {
|
if ($entity instanceof NotifyPropertyChanged) {
|
||||||
$entity->addPropertyChangedListener($this);
|
$entity->addPropertyChangedListener($this);
|
||||||
}
|
}
|
||||||
$overrideLocalValues = true;
|
$overrideLocalValues = true;
|
||||||
@ -1727,6 +1744,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* INTERNAL:
|
* INTERNAL:
|
||||||
* Sets a property value of the original data array of an entity.
|
* Sets a property value of the original data array of an entity.
|
||||||
*
|
*
|
||||||
|
* @ignore
|
||||||
* @param string $oid
|
* @param string $oid
|
||||||
* @param string $property
|
* @param string $property
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
@ -1856,7 +1874,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
* @param array $id The identifier values.
|
* @param array $id The identifier values.
|
||||||
* @param array $data The original entity data.
|
* @param array $data The original entity data.
|
||||||
*/
|
*/
|
||||||
public function registerManaged($entity, $id, $data)
|
public function registerManaged($entity, array $id, array $data)
|
||||||
{
|
{
|
||||||
$oid = spl_object_hash($entity);
|
$oid = spl_object_hash($entity);
|
||||||
$this->_entityIdentifiers[$oid] = $id;
|
$this->_entityIdentifiers[$oid] = $id;
|
||||||
|
@ -108,6 +108,8 @@ class CmsUser
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAddress() { return $this->address; }
|
||||||
|
|
||||||
public function setAddress(CmsAddress $address) {
|
public function setAddress(CmsAddress $address) {
|
||||||
if ($this->address !== $address) {
|
if ($this->address !== $address) {
|
||||||
$this->address = $address;
|
$this->address = $address;
|
||||||
|
@ -349,4 +349,86 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->_em->refresh($user);
|
$this->_em->refresh($user);
|
||||||
$this->assertEquals('developer', $user->status);
|
$this->assertEquals('developer', $user->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAddToCollectionDoesNotInitialize()
|
||||||
|
{
|
||||||
|
$this->_em->getConfiguration()->setAllowPartialObjects(false);
|
||||||
|
|
||||||
|
$user = new CmsUser;
|
||||||
|
$user->name = 'Guilherme';
|
||||||
|
$user->username = 'gblanco';
|
||||||
|
$user->status = 'developer';
|
||||||
|
|
||||||
|
for ($i=0; $i<3; ++$i) {
|
||||||
|
$phone = new CmsPhonenumber;
|
||||||
|
$phone->phonenumber = 100 + $i;
|
||||||
|
$user->addPhonenumber($phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_em->persist($user);
|
||||||
|
$this->_em->flush();
|
||||||
|
$this->_em->clear();
|
||||||
|
|
||||||
|
$this->assertEquals(3, $user->getPhonenumbers()->count());
|
||||||
|
|
||||||
|
$query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'");
|
||||||
|
|
||||||
|
$gblanco = $query->getSingleResult();
|
||||||
|
|
||||||
|
$this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
|
||||||
|
|
||||||
|
$newPhone = new CmsPhonenumber;
|
||||||
|
$phone->phonenumber = 555;
|
||||||
|
$gblanco->addPhonenumber($phone);
|
||||||
|
|
||||||
|
$this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
|
||||||
|
|
||||||
|
$this->_em->flush();
|
||||||
|
$this->_em->clear();
|
||||||
|
|
||||||
|
$query = $this->_em->createQuery("select u, p from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p where u.username='gblanco'");
|
||||||
|
$gblanco2 = $query->getSingleResult();
|
||||||
|
$this->assertEquals(4, $gblanco2->getPhonenumbers()->count());
|
||||||
|
|
||||||
|
$this->_em->getConfiguration()->setAllowPartialObjects(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetSetAssociationWithGetReference()
|
||||||
|
{
|
||||||
|
$user = new CmsUser;
|
||||||
|
$user->name = 'Guilherme';
|
||||||
|
$user->username = 'gblanco';
|
||||||
|
$user->status = 'developer';
|
||||||
|
$this->_em->persist($user);
|
||||||
|
|
||||||
|
$address = new CmsAddress;
|
||||||
|
$address->country = 'Germany';
|
||||||
|
$address->city = 'Berlin';
|
||||||
|
$address->zip = '12345';
|
||||||
|
$this->_em->persist($address);
|
||||||
|
|
||||||
|
$this->_em->flush();
|
||||||
|
$this->_em->detach($address);
|
||||||
|
|
||||||
|
$this->assertFalse($this->_em->contains($address));
|
||||||
|
$this->assertTrue($this->_em->contains($user));
|
||||||
|
|
||||||
|
// Assume we only got the identifier of the address and now want to attach
|
||||||
|
// that address to the user without actually loading it, using getReference().
|
||||||
|
$addressRef = $this->_em->getReference('Doctrine\Tests\Models\CMS\CmsAddress', $address->getId());
|
||||||
|
|
||||||
|
$user->setAddress($addressRef);
|
||||||
|
|
||||||
|
$this->_em->flush();
|
||||||
|
$this->_em->clear();
|
||||||
|
|
||||||
|
// Check with a fresh load that the association is indeed there
|
||||||
|
$query = $this->_em->createQuery("select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.address a where u.username='gblanco'");
|
||||||
|
$gblanco = $query->getSingleResult();
|
||||||
|
|
||||||
|
$this->assertTrue($gblanco instanceof CmsUser);
|
||||||
|
$this->assertTrue($gblanco->getAddress() instanceof CmsAddress);
|
||||||
|
$this->assertEquals('Berlin', $gblanco->getAddress()->getCity());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user