{"record":{"id":"7cafb70f82fb71d1","repo":"doctrine/orm","slug":"not-all-identifier-properties-can-be-found-in-the-7cafb7","errorCode":null,"errorMessage":"Not all identifier properties can be found in the ResultSetMapping: %s","messagePattern":"Not all identifier properties can be found in the ResultSetMapping: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Tools/Pagination/LimitSubqueryOutputWalker.php","lineNumber":554,"sourceCode":"            if (isset($rootClass->associationMappings[$property])) {\n                $association = $rootClass->associationMappings[$property];\n                assert($association->isToOneOwningSide());\n                $joinColumn = $association->joinColumns[0]->name;\n\n                foreach (array_keys($this->rsm->metaMappings, $joinColumn, true) as $alias) {\n                    if ($this->rsm->columnOwnerMap[$alias] === $rootAlias) {\n                        $sqlIdentifier[$property] = $alias;\n                    }\n                }\n            }\n        }\n\n        if (count($sqlIdentifier) === 0) {\n            throw new RuntimeException('The Paginator does not support Queries which only yield ScalarResults.');\n        }\n\n        if (count($rootIdentifier) !== count($sqlIdentifier)) {\n            throw new RuntimeException(sprintf(\n                'Not all identifier properties can be found in the ResultSetMapping: %s',\n                implode(', ', array_diff($rootIdentifier, array_keys($sqlIdentifier))),\n            ));\n        }\n\n        return $sqlIdentifier;\n    }\n\n    public function walkPathExpression(PathExpression $pathExpr): string\n    {\n        if (! $this->inSubSelect && ! $this->platformSupportsRowNumber() && ! in_array($pathExpr, $this->orderByPathExpressions, true)) {\n            $this->orderByPathExpressions[] = $pathExpr;\n        }\n\n        return parent::walkPathExpression($pathExpr);\n    }\n\n    public function walkSubSelect(Subselect $subselect): string","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/doctrine/orm/blob/d9b9ff73016bf598ae07515f97289ce8074e97a5/src/Tools/Pagination/LimitSubqueryOutputWalker.php#L536-L572","documentation":"Thrown by Doctrine ORM's Paginator (LimitSubqueryOutputWalker::getSQLIdentifier, called when output walkers build the row-number LIMIT subquery) when not every identifier property of the paginated root entity can be matched to a column in the query's ResultSetMapping. The paginator needs the SQL alias of each identifier column to build its WHERE id IN (...) subquery, so if the select list omits part of the primary key (field or association join column), pagination is impossible. The message lists exactly which identifier properties are missing.","triggerScenarios":"Iterating a Paginator over a DQL query whose ResultSetMapping lacks one or more root identifier columns: a PARTIAL select that omits an id field (SELECT partial u.{name, email} with 'id' missing), a composite primary key where one part is a to-one association whose join column is not selected, or a manually applied ResultSetMapping that skips an id column.","commonSituations":"Performance-tuned API list endpoints that use PARTIAL selects; entities with composite keys mixing fields and associations; queries migrated to partial selects while Paginator was already in place; SELECT new .../scalar-heavy queries where the entity id is only partially selected.","solutions":["Add the missing identifier property(s) named in the message to the PARTIAL select, e.g. SELECT partial u.{id, name, email}.","Remove PARTIAL and select the whole entity (SELECT u FROM App\\Entity\\User u) so the RSM always contains all id columns.","For composite keys containing a to-one association, include that association in the select so its join column gets a meta mapping.","If you only need scalar rows, skip Paginator and page manually with setFirstResult()/setMaxResults()."],"exampleFix":"// before\n$dql = 'SELECT partial u.{name, email} FROM App\\\\Entity\\\\User u ORDER BY u.name';\n$paginator = new Paginator($query); // RuntimeException: Not all identifier properties can be found...\n\n// after\n$dql = 'SELECT partial u.{id, name, email} FROM App\\\\Entity\\\\User u ORDER BY u.name';\n$paginator = new Paginator($query);","handlingStrategy":"validation","validationCode":"// Before iterating the Paginator, verify every root identifier property maps into the RSM\n$class = $em->getClassMetadata($rootEntityClass);\n$query->getSQL(); // force parse so the RSM exists\n$rsm = $query->getResultSetMapping();\n\n$missing = [];\nforeach ($class->getIdentifierFieldNames() as $field) {\n    $present = isset($class->fieldMappings[$field])\n        ? in_array($field, $rsm->fieldMappings, true)\n        : in_array($class->associationMappings[$field]->joinColumns[0]->name, $rsm->metaMappings, true);\n    if (! $present) {\n        $missing[] = $field;\n    }\n}\n\nif ($missing !== []) {\n    throw new InvalidArgumentException('Paginator would fail, missing id fields: ' . implode(', ', $missing));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never omit identifier fields from PARTIAL selects that feed a Paginator","Add a smoke test that iterates every paginated list query in CI","Prefer full-entity selects over PARTIAL for paginated queries"],"tags":["doctrine-orm","paginator","pagination","result-set-mapping","composite-key","partial-select","dql"],"backgroundTag":"orm-paginator-identifier-mapping","analyzedSha":"d9b9ff73016bf598ae07515f97289ce8074e97a5","analyzedAt":"2026-08-21T06:13:15.863Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}