diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index e1667add2..216fca542 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -28,7 +28,7 @@ use Doctrine\ORM\Cache\QueryCacheKey; use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\ORM\Cache; -use Doctrine\ORM\Query\QueryException; +use Doctrine\ORM\Query\ResultSetMapping; /** * Base contract for ORM queries. Base class for Query and NativeQuery. @@ -993,32 +993,54 @@ abstract class AbstractQuery private function executeUsingQueryCache($parameters = null, $hydrationMode = null) { $rsm = $this->getResultSetMapping(); - $querykey = new QueryCacheKey($this->getHash(), $this->lifetime, $this->cacheMode ?: Cache::MODE_NORMAL); $queryCache = $this->_em->getCache()->getQueryCache($this->cacheRegion); - $result = $queryCache->get($querykey, $rsm, $this->_hints); + $queryKey = new QueryCacheKey( + $this->getHash(), + $this->lifetime, + $this->cacheMode ?: Cache::MODE_NORMAL, + $this->getTimestampKey() + ); + + $result = $queryCache->get($queryKey, $rsm, $this->_hints); if ($result !== null) { if ($this->cacheLogger) { - $this->cacheLogger->queryCacheHit($queryCache->getRegion()->getName(), $querykey); + $this->cacheLogger->queryCacheHit($queryCache->getRegion()->getName(), $queryKey); } return $result; } $result = $this->executeIgnoreQueryCache($parameters, $hydrationMode); - $cached = $queryCache->put($querykey, $rsm, $result, $this->_hints); + $cached = $queryCache->put($queryKey, $rsm, $result, $this->_hints); if ($this->cacheLogger) { - $this->cacheLogger->queryCacheMiss($queryCache->getRegion()->getName(), $querykey); + $this->cacheLogger->queryCacheMiss($queryCache->getRegion()->getName(), $queryKey); if ($cached) { - $this->cacheLogger->queryCachePut($queryCache->getRegion()->getName(), $querykey); + $this->cacheLogger->queryCachePut($queryCache->getRegion()->getName(), $queryKey); } } return $result; } + /** + * @return \Doctrine\ORM\Cache\TimestampCacheKey|null + */ + private function getTimestampKey() + { + $entityName = reset($this->_resultSetMapping->aliasMap); + + if (empty($entityName)) { + return null; + } + + $metadata = $this->_em->getClassMetadata($entityName); + + return new Cache\TimestampCacheKey($metadata->getTableName()); + } + /** * Get the result cache id to use to store the result set cache entry. * Will return the configured id if it exists otherwise a hash will be diff --git a/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php b/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php index eaead7cf7..ba850ed9d 100644 --- a/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php +++ b/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php @@ -381,13 +381,13 @@ abstract class AbstractEntityPersister implements CachedEntityPersister $query = $this->persister->getSelectSQL($criteria, null, null, $limit, null, $orderBy); $hash = $this->getHash($query, $criteria, null, null, null, $timestamp ? $timestamp->time : null); $rsm = $this->getResultSetMapping(); - $querykey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL); + $queryKey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey); $queryCache = $this->cache->getQueryCache($this->regionName); - $result = $queryCache->get($querykey, $rsm); + $result = $queryCache->get($queryKey, $rsm); if ($result !== null) { if ($this->cacheLogger) { - $this->cacheLogger->queryCacheHit($this->regionName, $querykey); + $this->cacheLogger->queryCacheHit($this->regionName, $queryKey); } return $result[0]; @@ -397,15 +397,15 @@ abstract class AbstractEntityPersister implements CachedEntityPersister return null; } - $cached = $queryCache->put($querykey, $rsm, array($result)); + $cached = $queryCache->put($queryKey, $rsm, array($result)); if ($this->cacheLogger) { if ($result) { - $this->cacheLogger->queryCacheMiss($this->regionName, $querykey); + $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey); } if ($cached) { - $this->cacheLogger->queryCachePut($this->regionName, $querykey); + $this->cacheLogger->queryCachePut($this->regionName, $queryKey); } } @@ -421,28 +421,28 @@ abstract class AbstractEntityPersister implements CachedEntityPersister $query = $this->persister->getSelectSQL($criteria, null, null, $limit, $offset, $orderBy); $hash = $this->getHash($query, $criteria, null, null, null, $timestamp ? $timestamp->time : null); $rsm = $this->getResultSetMapping(); - $querykey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL); + $queryKey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey); $queryCache = $this->cache->getQueryCache($this->regionName); - $result = $queryCache->get($querykey, $rsm); + $result = $queryCache->get($queryKey, $rsm); if ($result !== null) { if ($this->cacheLogger) { - $this->cacheLogger->queryCacheHit($this->regionName, $querykey); + $this->cacheLogger->queryCacheHit($this->regionName, $queryKey); } return $result; } $result = $this->persister->loadAll($criteria, $orderBy, $limit, $offset); - $cached = $queryCache->put($querykey, $rsm, $result); + $cached = $queryCache->put($queryKey, $rsm, $result); if ($this->cacheLogger) { if ($result) { - $this->cacheLogger->queryCacheMiss($this->regionName, $querykey); + $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey); } if ($cached) { - $this->cacheLogger->queryCachePut($this->regionName, $querykey); + $this->cacheLogger->queryCachePut($this->regionName, $queryKey); } } @@ -520,28 +520,28 @@ abstract class AbstractEntityPersister implements CachedEntityPersister $timestamp = $this->timestampRegion->get($this->timestampKey); $hash = $this->getHash($query, $criteria, null, null, null, $timestamp ? $timestamp->time : null); $rsm = $this->getResultSetMapping(); - $querykey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL); + $queryKey = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey); $queryCache = $this->cache->getQueryCache($this->regionName); - $cacheResult = $queryCache->get($querykey, $rsm); + $cacheResult = $queryCache->get($queryKey, $rsm); if ($cacheResult !== null) { if ($this->cacheLogger) { - $this->cacheLogger->queryCacheHit($this->regionName, $querykey); + $this->cacheLogger->queryCacheHit($this->regionName, $queryKey); } return $cacheResult; } $result = $this->persister->loadCriteria($criteria); - $cached = $queryCache->put($querykey, $rsm, $result); + $cached = $queryCache->put($queryKey, $rsm, $result); if ($this->cacheLogger) { if ($result) { - $this->cacheLogger->queryCacheMiss($this->regionName, $querykey); + $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey); } if ($cached) { - $this->cacheLogger->queryCachePut($this->regionName, $querykey); + $this->cacheLogger->queryCachePut($this->regionName, $queryKey); } } diff --git a/lib/Doctrine/ORM/Cache/QueryCacheKey.php b/lib/Doctrine/ORM/Cache/QueryCacheKey.php index 9a7d2b7bc..0e072a36f 100644 --- a/lib/Doctrine/ORM/Cache/QueryCacheKey.php +++ b/lib/Doctrine/ORM/Cache/QueryCacheKey.php @@ -45,14 +45,27 @@ class QueryCacheKey extends CacheKey public $cacheMode; /** - * @param string $hash Result cache id - * @param integer $lifetime Query lifetime - * @param integer $cacheMode Query cache mode + * READ-ONLY: Public only for performance reasons, it should be considered immutable. + * + * @var TimestampCacheKey|null */ - public function __construct($hash, $lifetime = 0, $cacheMode = Cache::MODE_NORMAL) - { - $this->hash = $hash; - $this->lifetime = $lifetime; - $this->cacheMode = $cacheMode; + public $timestampKey; + + /** + * @param string $hash Result cache id + * @param integer $lifetime Query lifetime + * @param int $cacheMode Query cache mode + * @param TimestampCacheKey|null $timestampKey + */ + public function __construct( + $hash, + $lifetime = 0, + $cacheMode = Cache::MODE_NORMAL, + TimestampCacheKey $timestampKey = null + ) { + $this->hash = $hash; + $this->lifetime = $lifetime; + $this->cacheMode = $cacheMode; + $this->timestampKey = $timestampKey; } }