doctrine/orm · error · LengthException
Unexpected number of database columns.
Error message
Unexpected number of database columns.
What it means
JoinedSubclassPersister::fetchVersionAndNotUpsertableValues() combines the expected generated/version column keys with the columns returned by the re-select across the joined inheritance tables. If the combine comes back empty, the collected column list and the query result disagree — an internal mapping invariant break, typically caused by a stale or hand-built ClassMetadata (versionField or generated attribute not backed by a real field mapping).
Source
Thrown at src/Persisters/Entity/JoinedSubclassPersister.php:568
. ' FROM ' . $tableName . ' ' . $baseTableAlias
. $joinSql
. ' WHERE ' . implode(' = ? AND ', $identifier) . ' = ?';
$flatId = $this->identifierFlattener->flattenIdentifier($versionedClass, $id);
$values = $this->conn->fetchNumeric(
$sql,
array_values($flatId),
$this->extractIdentifierTypes($id, $versionedClass),
);
if ($values === false) {
throw new LengthException('Unexpected empty result for database query.');
}
$values = array_combine(array_keys($columnNames), $values);
if (! $values) {
throw new LengthException('Unexpected number of database columns.');
}
return $values;
}
private function getJoinSql(string $baseTableAlias): string
{
$joinSql = '';
$identifierColumn = $this->class->getIdentifierColumnNames();
// INNER JOIN parent tables
foreach ($this->class->parentClasses as $parentClassName) {
$conditions = [];
$parentClass = $this->em->getClassMetadata($parentClassName);
$tableAlias = $this->getSQLTableAlias($parentClassName);
$joinSql .= ' INNER JOIN ' . $this->quoteStrategy->getTableName($parentClass, $this->platform) . ' ' . $tableAlias . ' ON ';
foreach ($identifierColumn as $idColumn) {View on GitHub (pinned to d9b9ff7301)
Solutions
- Confirm the #[Version] and `generated` fields exist as real mapped columns in the entity (and parent classes)
- Clear the metadata cache after schema/mapping changes
- Log the SELECT built by fetchVersionAndNotUpsertableValues and compare with the class-field mapping
Defensive patterns
Strategy: validation
Validate before calling
$meta = $em->getClassMetadata($childEntity::class);
foreach ([$meta, ...array_map(fn($p) => $em->getClassMetadata($p), $meta->parentClasses)] as $m) {
if ($m->isVersioned && ! isset($m->fieldMappings[$m->versionField])) { throw new RuntimeException('Broken version metadata: ' . $m->name); }
} Prevention
- Clear metadata cache after inheritance-hierarchy mapping changes
- Keep #[Version] on one real column of the declaring class
- Run doctrine:schema:validate after mapping edits
When it happens
Trigger: Joined-inheritance entity marked versioned or carrying generated columns whose metadata drifts from the actual field mappings; cached metadata from before a rename of a versioned/generated field.
Common situations: Renaming version or generated fields without clearing metadata cache; programmatically assembled ClassMetadata for inheritance hierarchies.
Related errors
- Unexpected number of database columns.
- Unexpected empty result for database query.
- No Metadata cache driver is configured on given EntityManage
- No persister found for entity.
AI-assisted analysis of doctrine/orm@d9b9ff7301 (2026-08-21).
Data as JSON: /api/errors/b18e069ed4e0aef8.
Report an issue: GitHub.