1
0
mirror of synced 2024-12-15 07:36:03 +03:00

Merge branch 'DDC-1238'

This commit is contained in:
Benjamin Eberlei 2011-07-04 23:19:26 +02:00
commit 5c2a4c0339
7 changed files with 142 additions and 20 deletions

View File

@ -287,4 +287,25 @@ abstract class AbstractHydrator
return $rowData;
}
protected function registerManaged($class, $entity, $data)
{
if ($class->isIdentifierComposite) {
$id = array();
foreach ($class->identifier as $fieldName) {
if (isset($class->associationMappings[$fieldName])) {
$id[$fieldName] = $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']];
} else {
$id[$fieldName] = $data[$fieldName];
}
}
} else {
if (isset($class->associationMappings[$class->identifier[0]])) {
$id = array($class->identifier[0] => $data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']]);
} else {
$id = array($class->identifier[0] => $data[$class->identifier[0]]);
}
}
$this->_em->getUnitOfWork()->registerManaged($entity, $id, $data);
}
}

View File

@ -205,6 +205,12 @@ class ObjectHydrator extends AbstractHydrator
$className = $this->_ce[$className]->discriminatorMap[$data[$discrColumn]];
unset($data[$discrColumn]);
}
if (isset($this->_hints[Query::HINT_REFRESH_ENTITY]) && isset($this->_rootAliases[$dqlAlias])) {
$class = $this->_ce[$className];
$this->registerManaged($class, $this->_hints[Query::HINT_REFRESH_ENTITY], $data);
}
return $this->_uow->createEntity($className, $data, $this->_hints);
}

View File

@ -23,11 +23,10 @@ namespace Doctrine\ORM\Internal\Hydration;
use \PDO;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Query;
class SimpleObjectHydrator extends AbstractHydrator
{
const REFRESH_ENTITY = 'doctrine_refresh_entity';
/**
* @var ClassMetadata
*/
@ -123,17 +122,8 @@ class SimpleObjectHydrator extends AbstractHydrator
}
}
if (isset($this->_hints[self::REFRESH_ENTITY])) {
$this->_hints[Query::HINT_REFRESH] = true;
$id = array();
if ($this->_class->isIdentifierComposite) {
foreach ($this->_class->identifier as $fieldName) {
$id[$fieldName] = $data[$fieldName];
}
} else {
$id = array($this->_class->identifier[0] => $data[$this->_class->identifier[0]]);
}
$this->_em->getUnitOfWork()->registerManaged($this->_hints[self::REFRESH_ENTITY], $id, $data);
if (isset($this->_hints[Query::HINT_REFRESH_ENTITY])) {
$this->registerManaged($this->class, $this->_hints[Query::HINT_REFRESH_ENTITY], $data);
}
$result[] = $this->_em->getUnitOfWork()->createEntity($entityName, $data, $this->_hints);

View File

@ -570,6 +570,7 @@ class BasicEntityPersister
if ($entity !== null) {
$hints[Query::HINT_REFRESH] = true;
$hints[Query::HINT_REFRESH_ENTITY] = $entity;
}
if ($this->_selectJoinSql) {
@ -587,13 +588,12 @@ class BasicEntityPersister
*
* @param array $assoc The association to load.
* @param object $sourceEntity The entity that owns the association (not necessarily the "owning side").
* @param object $targetEntity The existing ghost entity (proxy) to load, if any.
* @param array $identifier The identifier of the entity to load. Must be provided if
* the association to load represents the owning side, otherwise
* the identifier is derived from the $sourceEntity.
* @return object The loaded and managed entity instance or NULL if the entity can not be found.
*/
public function loadOneToOneEntity(array $assoc, $sourceEntity, $targetEntity, array $identifier = array())
public function loadOneToOneEntity(array $assoc, $sourceEntity, array $identifier = array())
{
if ($foundEntity = $this->_em->getUnitOfWork()->tryGetById($identifier, $assoc['targetEntity'])) {
return $foundEntity;
@ -621,7 +621,7 @@ class BasicEntityPersister
}
*/
$targetEntity = $this->load($identifier, $targetEntity, $assoc, $hints);
$targetEntity = $this->load($identifier, null, $assoc, $hints);
// Complete bidirectional association, if necessary
if ($targetEntity !== null && $isInverseSingleValued) {
@ -641,7 +641,7 @@ class BasicEntityPersister
}
}
$targetEntity = $this->load($identifier, $targetEntity, $assoc);
$targetEntity = $this->load($identifier, null, $assoc);
if ($targetEntity !== null) {
$targetClass->setFieldValue($targetEntity, $assoc['mappedBy'], $sourceEntity);

View File

@ -53,6 +53,15 @@ final class Query extends AbstractQuery
* @var string
*/
const HINT_REFRESH = 'doctrine.refresh';
/**
* Internal hint: is set to the proxy entity that is currently triggered for loading
*
* @var string
*/
const HINT_REFRESH_ENTITY = 'doctrine.refresh.entity';
/**
* The forcePartialLoad query hint forces a particular query to return
* partial objects.

View File

@ -1976,7 +1976,7 @@ class UnitOfWork implements PropertyChangedListener
// a way to solve this with deferred eager loading, which means putting
// an entity with subclasses at a *-to-one location is really bad! (performance-wise)
$newValue = $this->getEntityPersister($assoc['targetEntity'])
->loadOneToOneEntity($assoc, $entity, null, $associatedId);
->loadOneToOneEntity($assoc, $entity, $associatedId);
} else {
// Deferred eager load only works for single identifier classes
@ -2012,7 +2012,7 @@ class UnitOfWork implements PropertyChangedListener
} else {
// Inverse side of x-to-one can never be lazy
$class->reflFields[$field]->setValue($entity, $this->getEntityPersister($assoc['targetEntity'])
->loadOneToOneEntity($assoc, $entity, null));
->loadOneToOneEntity($assoc, $entity));
}
} else {
// Inject collection

View File

@ -0,0 +1,96 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Tests\Models\CMS\CmsEmployee;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1238
*/
class DDC1238Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1238User'),
));
} catch(\PDOException $e) {
}
}
public function testIssue()
{
$user = new DDC1238User;
$user->setName("test");
$this->_em->persist($user);
$this->_em->flush();
$this->_em->clear();
$userId = $user->getId();
$this->_em->clear();
$user = $this->_em->getReference(__NAMESPACE__ . '\\DDC1238User', $userId);
$this->_em->clear();
$userId2 = $user->getId();
$this->assertEquals($userId, $userId2, "This proxy can still be initialized.");
}
public function testIssueProxyClear()
{
$user = new DDC1238User;
$user->setName("test");
$this->_em->persist($user);
$this->_em->flush();
$this->_em->clear();
$userId = $user->getId();
$this->_em->clear();
$user = $this->_em->getReference(__NAMESPACE__ . '\\DDC1238User', $userId);
$this->_em->clear();
$user2 = $this->_em->getReference(__NAMESPACE__ . '\\DDC1238User', $userId);
$this->assertNull($user->getId(), "Now this is null, we already have a user instance of that type");
}
}
/**
* @Entity
*/
class DDC1238User
{
/** @Id @GeneratedValue @Column(type="integer") */
private $id;
/**
* @Column
* @var string
*/
private $name;
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
}