{"record":{"id":"0cf19607af7afbc2","repo":"doctrine/orm","slug":"uninitialized-result-set-mapping","errorCode":null,"errorMessage":"Uninitialized result set mapping.","messagePattern":"Uninitialized result set mapping\\.","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"src/AbstractQuery.php","lineNumber":864,"sourceCode":"     * @phpstan-param string|AbstractQuery::HYDRATE_*|null    $hydrationMode\n     *\n     * @return iterable<mixed>\n     */\n    public function toIterable(\n        ArrayCollection|array $parameters = [],\n        string|int|null $hydrationMode = null,\n    ): iterable {\n        if ($hydrationMode !== null) {\n            $this->setHydrationMode($hydrationMode);\n        }\n\n        if (count($parameters) !== 0) {\n            $this->setParameters($parameters);\n        }\n\n        $rsm = $this->getResultSetMapping();\n        if ($rsm === null) {\n            throw new LogicException('Uninitialized result set mapping.');\n        }\n\n        $stmt = $this->_doExecute();\n\n        return $this->em->newHydrator($this->hydrationMode)->toIterable($stmt, $rsm, $this->hints);\n    }\n\n    /**\n     * Executes the query.\n     *\n     * @phpstan-param ArrayCollection<int, Parameter>|mixed[]|null $parameters\n     * @phpstan-param string|AbstractQuery::HYDRATE_*|null         $hydrationMode\n     */\n    public function execute(\n        ArrayCollection|array|null $parameters = null,\n        string|int|null $hydrationMode = null,\n    ): mixed {\n        if ($this->cacheable && $this->isCacheEnabled()) {","sourceCodeStart":846,"sourceCodeEnd":882,"githubUrl":"https://github.com/doctrine/orm/blob/d9b9ff73016bf598ae07515f97289ce8074e97a5/src/AbstractQuery.php#L846-L882","documentation":"LogicException thrown by AbstractQuery::toIterable() (src/AbstractQuery.php:864) when getResultSetMapping() returns null. A ResultSetMapping (RSM) tells the hydrator how to map SQL columns to entity/scalar aliases. Regular DQL Query objects build the RSM lazily by parsing the DQL; only queries whose RSM must be supplied manually can end up with a null one.","triggerScenarios":"Calling toIterable() on a NativeQuery (or a custom AbstractQuery subclass) that never had setResultSetMapping() called — typically a NativeQuery constructed with `new NativeQuery($em)` instead of EntityManager::createNativeQuery($sql, $rsm), or a hand-rolled AbstractQuery subclass whose _doExecute() returns a statement without an RSM.","commonSituations":"Migrating streaming/batch-processing code from getResult() to toIterable(); refactoring away from EntityManager::createNativeQuery() and losing the second constructor argument; custom query classes from internal frameworks that predate the RSM contract.","solutions":["Build native queries via EntityManager::createNativeQuery($sql, $rsm) — it calls setResultSetMapping() for you.","If you construct NativeQuery manually, call $query->setResultSetMapping($rsm) before toIterable(); build the RSM with ResultSetMappingBuilder->addEntityResult()/addScalarResult() or addRootEntityFromClassMetadata().","Prefer a DQL query ($em->createQuery()) when possible — its RSM is derived from the DQL automatically.","Audit custom AbstractQuery subclasses and make _doExecute() paths always leave a non-null RSM."],"exampleFix":"// before\n$query = new NativeQuery($em);\n$query->setSql('SELECT id, email FROM user WHERE active = 1');\nforeach ($query->toIterable() as $row) { ... } // LogicException: Uninitialized result set mapping.\n\n// after\n$rsm = new ResultSetMappingBuilder($em);\n$rsm->addRootEntityFromClassMetadata(User::class, 'u');\n$query = $em->createNativeQuery('SELECT id, email FROM user WHERE active = 1', $rsm);\nforeach ($query->toIterable() as $user) { ... }","handlingStrategy":"validation","validationCode":"// Only route queries with a known ResultSetMapping into toIterable()\nif ($query instanceof \\Doctrine\\ORM\\NativeQuery && ! $query->getSQL()) {\n    throw new LogicException('Native query lacks SQL/RSM setup');\n}\n// Build via the EM so the RSM is always attached:\n$query = $em->createNativeQuery($sql, $rsm);","typeGuard":null,"tryCatchPattern":"try {\n    foreach ($query->toIterable() as $row) { /* ... */ }\n} catch (\\LogicException $e) {\n    // misconfiguration at build time: fail fast with the query class/name in context\n}","preventionTips":["Always create native queries with EntityManager::createNativeQuery($sql, $rsm); never new NativeQuery() without setResultSetMapping().","Centralize query construction behind repository methods so RSM wiring cannot be forgotten.","Prefer DQL for iteration — its result-set mapping is derived automatically."],"tags":["doctrine-orm","native-query","result-set-mapping","to-iterate"],"backgroundTag":"missing-result-set-mapping","analyzedSha":"d9b9ff73016bf598ae07515f97289ce8074e97a5","analyzedAt":"2026-08-21T06:13:15.863Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}