-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GH-7633] disallow cache partial objects #8050
[GH-7633] disallow cache partial objects #8050
Conversation
There was a check in DefaultQueryCache that prevented partial queries, because they are not supported. However the checked hint Query::HINT_FORCE_PARTIAL_LOAD is optional, so cant be used to prevent caching partial DQL queries. Introduce a new hint that the SqlWalker sets on detecing a PARTIAL query and throw an exception in the DefaultQueryCache if thats found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! It's great that we have this being handled automatically now, thanks 👍
@@ -260,7 +260,7 @@ public function put(QueryCacheKey $key, ResultSetMapping $rsm, $result, array $h | |||
throw new CacheException("Second-level cache query supports only select statements."); | |||
} | |||
|
|||
if (isset($hints[Query\SqlWalker::HINT_PARTIAL]) && $hints[Query\SqlWalker::HINT_PARTIAL]) { | |||
if (($hints[Query\SqlWalker::HINT_PARTIAL] ?? false) === true || ($hints[Query::HINT_FORCE_PARTIAL_LOAD] ?? false) === true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then we can do this:
if (($hints[Query\SqlWalker::HINT_PARTIAL] ?? false) === true || ($hints[Query::HINT_FORCE_PARTIAL_LOAD] ?? false) === true) { | |
if (($hints[Query\SqlWalker::HINT_PARTIAL] ?? $hints[Query::HINT_FORCE_PARTIAL_LOAD] ?? false) === true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like to keep it this way now.
/** | ||
* @expectedException \Doctrine\ORM\Cache\CacheException | ||
* @expectedExceptionMessage Second level cache does not support partial entities. | ||
*/ | ||
public function testCacheableForcePartialLoadHintQueryException() | ||
{ | ||
$this->evictRegions(); | ||
$this->loadFixturesCountries(); | ||
|
||
$this->_em->createQuery("SELECT c FROM Doctrine\Tests\Models\Cache\Country c") | ||
->setCacheable(true) | ||
->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true) | ||
->getResult(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@expectedException
and @expectedExceptionMessage
have been deprecated in PHPUnit 8.x and removed in PHPUnit v9.0. We should avoid using them.
We might need to import Doctrine\ORM\Cache\CacheException
but this should be the way to go:
/** | |
* @expectedException \Doctrine\ORM\Cache\CacheException | |
* @expectedExceptionMessage Second level cache does not support partial entities. | |
*/ | |
public function testCacheableForcePartialLoadHintQueryException() | |
{ | |
$this->evictRegions(); | |
$this->loadFixturesCountries(); | |
$this->_em->createQuery("SELECT c FROM Doctrine\Tests\Models\Cache\Country c") | |
->setCacheable(true) | |
->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true) | |
->getResult(); | |
} | |
public function testCacheableForcePartialLoadHintQueryException() | |
{ | |
$this->evictRegions(); | |
$this->loadFixturesCountries(); | |
$this->expectException(CacheException::class); | |
$this->expectExceptionMessage('Second level cache does not support partial entities.'); | |
$this->_em->createQuery("SELECT c FROM Doctrine\Tests\Models\Cache\Country c") | |
->setCacheable(true) | |
->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true) | |
->getResult(); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
99 occurrences of this in tests on 2.7, i move this to a mainteance task for 2.8
There was a check in DefaultQueryCache that prevented partial queries,
because they are not supported. However the checked hint
Query::HINT_FORCE_PARTIAL_LOAD is optional, so cant be used to prevent
caching partial DQL queries.
Introduce a new hint that the SqlWalker sets on detecing a PARTIAL
query and throw an exception in the DefaultQueryCache if thats found.