doctrine/orm · error · QueryException
The hint "HINT_CACHE_EVICT" is not valid for select statemen
Error message
The hint "HINT_CACHE_EVICT" is not valid for select statements.
What it means
Query::HINT_CACHE_EVICT instructs the ORM to evict the second-level-cache entity region affected by a DQL statement. It only makes sense for UPDATE/DELETE: during execute(), evictEntityCacheRegion() inspects the AST and throws a QueryException if the statement is a SelectStatement, because a SELECT has no affected entity region to evict.
Source
Thrown at src/Query.php:334
assert($cache !== null);
$statements = (array) $executor->getSqlStatements(); // Type casted since it can either be a string or an array
foreach ($statements as $statement) {
$cacheKeys = $this->queryCacheProfile->generateCacheKeys($statement, $sqlParams, $types, $connectionParams);
$cache->deleteItem(reset($cacheKeys));
}
}
/**
* Evict entity cache region
*/
private function evictEntityCacheRegion(): void
{
$AST = $this->getAST();
if ($AST instanceof SelectStatement) {
throw new QueryException('The hint "HINT_CACHE_EVICT" is not valid for select statements.');
}
$className = $AST instanceof DeleteStatement
? $AST->deleteClause->abstractSchemaName
: $AST->updateClause->abstractSchemaName;
$this->em->getCache()->evictEntityRegion($className);
}
/**
* Processes query parameter mappings.
*
* @param array<list<int>> $paramMappings
*
* @return mixed[][]
* @phpstan-return array{0: list<mixed>, 1: array}
*
* @throws Query\QueryExceptionView on GitHub (pinned to d9b9ff7301)
Solutions
- Remove the HINT_CACHE_EVICT hint from SELECT queries — set it only on UPDATE/DELETE DQL
- To invalidate cached query/entity data after a select-driven change, evict explicitly: $em->getCache()->evictEntityRegion(Entity::class) or ->evictEntity(Entity::class, $id)
- Keep hint-setting conditional on the statement type when hints are configured centrally
Example fix
// before
$q = $em->createQuery('SELECT u FROM App\Entity\User u WHERE u.id = :id');
$q->setHint(Query::HINT_CACHE_EVICT, true); // throws on execute
// after
$q = $em->createQuery('SELECT u FROM App\Entity\User u WHERE u.id = :id');
// evict manually if needed:
$em->getCache()->evictEntity(User::class, $id); Defensive patterns
Strategy: validation
Validate before calling
// Only set the hint on UPDATE/DELETE DQL
if (in_array($queryType, ['update', 'delete'], true)) {
$query->setHint(Query::HINT_CACHE_EVICT, true);
} Try / catch
try { $result = $query->execute(); } catch (QueryException $e) { if (str_contains($e->getMessage(), 'HINT_CACHE_EVICT')) { $query->setHint(Query::HINT_CACHE_EVICT, false); $result = $query->execute(); } else { throw $e; } } Prevention
- Set HINT_CACHE_EVICT only on UPDATE/DELETE statements
- Centralize hint configuration and gate it by statement type
- Prefer explicit $em->getCache()->evictEntityRegion() for invalidation
When it happens
Trigger: $query->setHint(Query::HINT_CACHE_EVICT, true) followed by executing a SELECT DQL query while second-level cache is enabled (hasCache) — the check runs in _doExecute() before parameter processing.
Common situations: Copy-pasting a cache-eviction hint between queries; applying the hint to a query builder that later becomes a select; blindly enabling all cache hints when turning on the second-level cache.
Related errors
- Unable to use access strategy type of [%s] without a Concurr
- Unrecognized access strategy type [%s]
- If you want to use a "READ_WRITE" cache an implementation of
- The directory "%s" does not exist and could not be created.
- The directory "%s" is not writable.
AI-assisted analysis of doctrine/orm@d9b9ff7301 (2026-08-21).
Data as JSON: /api/errors/82970b30183e52b3.
Report an issue: GitHub.