{"record":{"id":"acebcaaa439fbe7b","repo":"mybatis/mybatis-3","slug":"error-getting-constructor-collection-nested-result","errorCode":null,"errorMessage":"Error getting constructor collection nested result map values for '\" + constructorMapping.getProperty() + \"'.  Cause: \" + e","messagePattern":"Error getting constructor collection nested result map values for '\" \\+ constructorMapping\\.getProperty\\(\\) \\+ \"'\\.  Cause: \" \\+ e","errorType":"exception","errorClass":"ExecutorException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java","lineNumber":1340,"sourceCode":"          continue;\n        }\n\n        if (rowValue instanceof PendingConstructorCreation) {\n          if (newValueForNestedResultMap) {\n            // we created a brand new pcc. this is a new collection value\n            pendingConstructorCreation.linkCreation(constructorMapping, (PendingConstructorCreation) rowValue);\n            foundValues = true;\n          }\n        } else {\n          pendingConstructorCreation.linkCollectionValue(constructorMapping, rowValue);\n          foundValues = true;\n\n          if (combinedKey != CacheKey.NULL_CACHE_KEY) {\n            nestedResultObjects.put(combinedKey, pendingConstructorCreation);\n          }\n        }\n      } catch (SQLException e) {\n        throw new ExecutorException(\"Error getting constructor collection nested result map values for '\"\n            + constructorMapping.getProperty() + \"'.  Cause: \" + e, e);\n      }\n    }\n\n    return foundValues;\n  }\n\n  private void createPendingConstructorCreations(Object rowValue) {\n    // handle possible pending creations within this object\n    // by now, the property mapping has been completely built, we can reconstruct it\n    final PendingRelation pendingRelation = pendingPccRelations.remove(rowValue);\n    final MetaObject metaObject = pendingRelation.metaObject;\n    final ResultMapping resultMapping = pendingRelation.propertyMapping;\n\n    // get the list to be built\n    Object collectionProperty = instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject);\n    if (collectionProperty != null) {\n      // we expect pending creations now","sourceCodeStart":1322,"sourceCodeEnd":1358,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java#L1322-L1358","documentation":"A JDBC SQLException escaped while MyBatis was reading column values to build a nested (collection) result that feeds a constructor argument. MyBatis wraps it in an ExecutorException naming the constructor mapping property, preserving the original SQLException as the cause. The root cause is nearly always the underlying JDBC problem (bad column name/type read, closed cursor), not the mapping topology itself.","triggerScenarios":"A resultMap with <constructor> containing a <collection> (collection mapped into a constructor argument via nested result maps); while reading rows for the nested collection the driver throws SQLException — e.g. type handler calls resultSet.getXxx with a column absent from the nested query, an incompatible type conversion, or cursor/streaming limits.","commonSituations":"Mapping collections into immutable objects via constructor collection mappings; column name typos in nested select columns; DB type mismatches (e.g. reading a VARCHAR column as an INT handler); driver limitations on open result sets with multiple result sets (see sibling limitation error 'Cannot construct objects with collections in constructors using multiple result sets yet!').","solutions":["Inspect the wrapped cause (SQLException) — fix the actual JDBC-level problem it names (unknown column, type mismatch, closed result set).","Verify the nested collection's resultMap column names/types match the actual result set columns.","Verify a suitable TypeHandler is registered for the nested element Java type / JDBC type combination.","If using multiple result sets with constructor collections, restructure to a single result set or move the collection to a setter mapping — that combination is explicitly unsupported (separate error)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  List<Order> orders = session.selectList(\"selectOrdersWithItems\");\n} catch (PersistenceException e) {\n  Throwable root = Stream.iterate(e, Throwable::getCause)\n      .takeWhile(Objects::nonNull).reduce((a, r) -> r).orElse(e);\n  if (root instanceof SQLException sqlEx\n      && e.getMessage().contains(\"constructor collection nested result map\")) {\n    // driver-level failure while reading nested rows: surface column/type info\n    log.error(\"Nested constructor collection read failed: sqlState={}, msg={}\",\n        sqlEx.getSQLState(), sqlEx.getMessage());\n  }\n  throw e;\n}","preventionTips":["Always log the cause chain; the actionable detail is in the SQLException, not the wrapper.","Smoke-test nested constructor-collection maps against the real DB in CI so column/type mismatches surface before production.","Keep nested resultMap column names in sync with SELECT aliases via a shared constants file or codegen."],"tags":["mybatis","nested-results","collections","jdbc","constructor-mapping"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}