1
0
mirror of synced 2024-12-05 03:06:05 +03:00

[SLC] resolve association cache entry

This commit is contained in:
Fabio B. Silva 2014-03-06 19:42:43 -05:00
parent ecf242f6d4
commit e9ec0a24da
5 changed files with 120 additions and 15 deletions

View File

@ -89,7 +89,7 @@ class DefaultCollectionHydrator implements CollectionHydrator
return null;
}
$list[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->data, self::$hints);
$list[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->resolveAssociationEntries($this->em), self::$hints);
}
array_walk($list, function($entity, $index) use ($collection) {

View File

@ -144,7 +144,7 @@ class DefaultEntityHydrator implements EntityHydrator
return null;
}
$data[$name] = $this->uow->createEntity($assocEntry->class, $assocEntry->data, $hints);
$data[$name] = $this->uow->createEntity($assocEntry->class, $assocEntry->resolveAssociationEntries($this->em), $hints);
}
if ($entity !== null) {

View File

@ -108,7 +108,6 @@ class DefaultQueryCache implements QueryCache
$entityName = reset($rsm->aliasMap);
$hasRelation = ( ! empty($rsm->relationMap));
$persister = $this->uow->getEntityPersister($entityName);
$metadata = ( ! $hasRelation) ? $persister->getClassMetadata() : null;
$region = $persister->getCacheRegion();
$regionName = $region->getName();
@ -127,22 +126,16 @@ class DefaultQueryCache implements QueryCache
if ($this->cacheLogger !== null) {
$this->cacheLogger->entityCacheHit($regionName, $entityKey);
}
$data = $entityEntry->data;
if ( ! $hasRelation) {
foreach ($metadata->associationMappings as $name => $assoc) {
if ( ! ($assoc['type'] & ClassMetadata::TO_ONE) || ! isset($assoc['cache']) || ! isset($data[$name])) {
continue;
}
$data[$name] = $this->em->getReference($data[$name]->class, $data[$name]->identifier);
}
$result[$index] = $this->uow->createEntity($entityEntry->class, $data, self::$hints);
$result[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->resolveAssociationEntries($this->em), self::$hints);
continue;
}
$data = $entityEntry->data;
foreach ($entry['associations'] as $name => $assoc) {
$assocPersister = $this->uow->getEntityPersister($assoc['targetEntity']);
@ -159,7 +152,7 @@ class DefaultQueryCache implements QueryCache
return null;
}
$data[$name] = $this->uow->createEntity($assocEntry->class, $assocEntry->data, self::$hints);
$data[$name] = $this->uow->createEntity($assocEntry->class, $assocEntry->resolveAssociationEntries($this->em), self::$hints);
if ($this->cacheLogger !== null) {
$this->cacheLogger->entityCacheHit($assocRegion->getName(), $assocKey);
@ -186,7 +179,7 @@ class DefaultQueryCache implements QueryCache
return null;
}
$element = $this->uow->createEntity($assocEntry->class, $assocEntry->data, self::$hints);
$element = $this->uow->createEntity($assocEntry->class, $assocEntry->resolveAssociationEntries($this->em), self::$hints);
$collection->hydrateSet($assocIndex, $element);

View File

@ -20,6 +20,8 @@
namespace Doctrine\ORM\Cache;
use Doctrine\ORM\EntityManagerInterface;
/**
* Entity cache entry
*
@ -63,4 +65,22 @@ class EntityCacheEntry implements CacheEntry
{
return new self($values['class'], $values['data']);
}
/**
* Retrieves the entity data resolving cache entries
*
* @param \Doctrine\ORM\EntityManagerInterfac $em
*
* @return array
*/
public function resolveAssociationEntries(EntityManagerInterface $em)
{
return array_map(function($value) use ($em) {
if ( ! ($value instanceof AssociationCacheEntry)) {
return $value;
}
return $em->getReference($value->class, $value->identifier);
}, $this->data);
}
}

View File

@ -827,7 +827,7 @@ class SecondLevelCacheQueryCacheTest extends SecondLevelCacheAbstractTest
$this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount('bar_region'));
}
public function testToOneAssociationShouldUseProxyForCacheableMetaResultColumn()
public function testResolveAssociationCacheEntry()
{
$this->evictRegions();
$this->loadFixturesCountries();
@ -875,6 +875,98 @@ class SecondLevelCacheQueryCacheTest extends SecondLevelCacheAbstractTest
$this->assertEquals($stateId, $state2->getId());
}
public function testResolveToOneAssociationCacheEntry()
{
$this->evictRegions();
$this->loadFixturesCountries();
$this->loadFixturesStates();
$this->loadFixturesCities();
$this->evictRegions();
$this->_em->clear();
$cityId = $this->cities[0]->getId();
$dql = 'SELECT c, s FROM Doctrine\Tests\Models\Cache\City c JOIN c.state s WHERE c.id = :id';
$query = $this->_em->createQuery($dql);
$queryCount = $this->getCurrentQueryCount();
$query1 = clone $query;
$city1 = $query1
->setParameter('id', $cityId)
->setCacheable(true)
->setMaxResults(1)
->getSingleResult();
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\City', $city1);
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\State', $city1->getState());
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\City', $city1->getState()->getCities()->get(0));
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\State', $city1->getState()->getCities()->get(0)->getState());
$this->_em->clear();
$queryCount = $this->getCurrentQueryCount();
$query2 = clone $query;
$city2 = $query2
->setParameter('id', $cityId)
->setCacheable(true)
->setMaxResults(1)
->getSingleResult();
$this->assertEquals($queryCount, $this->getCurrentQueryCount());
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\City', $city2);
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\State', $city2->getState());
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\City', $city2->getState()->getCities()->get(0));
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\State', $city2->getState()->getCities()->get(0)->getState());
}
public function testResolveToManyAssociationCacheEntry()
{
$this->evictRegions();
$this->loadFixturesCountries();
$this->loadFixturesStates();
$this->loadFixturesCities();
$this->evictRegions();
$this->_em->clear();
$stateId = $this->states[0]->getId();
$dql = 'SELECT s, c FROM Doctrine\Tests\Models\Cache\State s JOIN s.cities c WHERE s.id = :id';
$query = $this->_em->createQuery($dql);
$queryCount = $this->getCurrentQueryCount();
$query1 = clone $query;
$state1 = $query1
->setParameter('id', $stateId)
->setCacheable(true)
->setMaxResults(1)
->getSingleResult();
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\State', $state1);
$this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $state1->getCountry());
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\City', $state1->getCities()->get(0));
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\State', $state1->getCities()->get(0)->getState());
$this->assertSame($state1, $state1->getCities()->get(0)->getState());
$this->_em->clear();
$queryCount = $this->getCurrentQueryCount();
$query2 = clone $query;
$state2 = $query2
->setParameter('id', $stateId)
->setCacheable(true)
->setMaxResults(1)
->getSingleResult();
$this->assertEquals($queryCount, $this->getCurrentQueryCount());
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\State', $state2);
$this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $state2->getCountry());
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\City', $state2->getCities()->get(0));
$this->assertInstanceOf('Doctrine\Tests\Models\Cache\State', $state2->getCities()->get(0)->getState());
$this->assertSame($state2, $state2->getCities()->get(0)->getState());
}
public function testHintClearEntityRegionUpdateStatement()
{
$this->evictRegions();