[SLC] resolve association cache entry
This commit is contained in:
parent
ecf242f6d4
commit
e9ec0a24da
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user