doctrine/orm · error · RuntimeException

No persister found for entity.

Error message

No persister found for entity.

What it means

UnitOfWork::getEntityPersister() selects a persister by the class's inheritance type: no inheritance -> BasicEntityPersister, SINGLE_TABLE -> SingleTablePersister, JOINED -> JoinedSubclassPersister. Any other inheritance type has no persister implementation - in practice TABLE_PER_CLASS, which Doctrine ORM persisters have never implemented - so the default arm of the match throws for every load/save operation on such an entity.

Source

Thrown at src/UnitOfWork.php:2931

    /**
     * Gets the EntityPersister for an Entity.
     *
     * @param class-string $entityName The name of the Entity.
     */
    public function getEntityPersister(string $entityName): EntityPersister
    {
        if (isset($this->persisters[$entityName])) {
            return $this->persisters[$entityName];
        }

        $class = $this->em->getClassMetadata($entityName);

        $persister = match (true) {
            $class->isInheritanceTypeNone() => new BasicEntityPersister($this->em, $class),
            $class->isInheritanceTypeSingleTable() => new SingleTablePersister($this->em, $class),
            $class->isInheritanceTypeJoined() => new JoinedSubclassPersister($this->em, $class),
            default => throw new RuntimeException('No persister found for entity.'),
        };

        if ($this->hasCache && $class->cache !== null) {
            $persister = $this->em->getConfiguration()
                ->getSecondLevelCacheConfiguration()
                ->getCacheFactory()
                ->buildCachedEntityPersister($this->em, $persister, $class);
        }

        $this->persisters[$entityName] = $persister;

        return $this->persisters[$entityName];
    }

    /** Gets a collection persister for a collection-valued association. */
    public function getCollectionPersister(AssociationMapping $association): CollectionPersister
    {
        $role = isset($association->cache)

View on GitHub (pinned to d9b9ff7301)

Solutions

  1. Clear and rebuild the metadata cache after changing inheritance mapping (bin/console cache:clear, doctrine orm:clear-cache:metadata).
  2. Switch the class to a supported strategy: SINGLE_TABLE or JOINED, or drop inheritance for a standalone entity.
  3. If the metadata is hand-built (custom metadata factory/generator), fix it to emit one of the three supported inheritance types.
Defensive patterns

Strategy: validation

Validate before calling

// At boot/build time, assert every entity uses a persister-supported inheritance type
foreach ($metadataFactory->getAllMetadata() as $class) {
    $supported = $class->isInheritanceTypeNone()
        || $class->isInheritanceTypeSingleTable()
        || $class->isInheritanceTypeJoined();
    if (! $supported) {
        throw new InvalidArgumentException($class->getName() . ' uses an unsupported inheritance type');
    }
}

Prevention

When it happens

Trigger: Any EntityManager operation (find, persist, flush, lazy-load, collection access) on an entity whose ClassMetadata inheritanceType is neither NONE, SINGLE_TABLE nor JOINED - typically TABLE_PER_CLASS (4) coming from hand-crafted metadata or stale cached metadata after an inheritance-mapping change that was deployed without invalidating the metadata cache.

Common situations: Metadata caches (APCu, file, Redis) not cleared after editing #[InheritanceType] attributes; experimenting with TABLE_PER_CLASS inheritance; custom metadata factories producing an unsupported type; deploying mapping changes across a cluster where one node serves old cached metadata.

Related errors


AI-assisted analysis of doctrine/orm@d9b9ff7301 (2026-08-21). Data as JSON: /api/errors/a870628d5e7dcf8c. Report an issue: GitHub.