doctrine / doctrine/DoctrineBundle
Auto-discover entities based on attribute
- Dominant language
- PHP
- Stars
- 4.8k
- Forks
- 482
- Avg merge
- 1h 51m
- Merged PRs (30d)
- 3
Description
### Feature Request
#### What
Automatically detect and register entity mappings by scanning for classes with the `#[Entity]` attribute when no explicit mappings are configured, eliminating the need for repetitive manual configuration.
#### Why
Currently, every entity mapping must be explicitly declared in `doctrine.yaml`:
```yaml
doctrine:
orm:
mappings:
User:
type: attribute
is_bundle: false
dir: '%kernel.project_dir%/src/User/Entity'
prefix: 'App\User\Entity'
alias: User
Event:
type: attribute
is_bundle: false
dir: '%kernel.project_dir%/src/Event/Entity'
prefix: 'App\Event\Entity'
alias: Event
# ... repeated for each domain
```
This becomes particularly tedious in DDD-structured projects with multiple bounded contexts, where entities are distributed across many domain folders. Going for a auto discover offers multiple benefits:
- Drastically reduces boilerplate configuration
- Aligns with "convention over configuration" philosophy
- Complements Symfony 7.3's auto-exclusion of entities from service container (PR [#59987](https://github.com/symfony/symfony/pull/59987))
- Complements Symfony 7.4's controllers auto-registering (PR [#61492](https://github.com/symfony/symfony/pull/61492))
- Provides DX similar to other ORMs (Laravel Eloquent, TypeORM, Hibernate)
- Fully backwards compatible with below option.
#### How
Half the work already exists. Since Symfony 7.3 (PR [#59987](https://github.com/symfony/symfony/pull/59987)), the service container scan already reads #[Entity] on every class of src/ to auto-exclude it from the container ([FrameworkExtension.php#L807](https://github.com/symfony/symfony/blob/7.3/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php#L807)):
```php
$container->registerAttributeForAutoconfiguration(Entity::class, static function (ChildDefinition $definition) {
$definition->addTag('container.excluded', ['source' => 'because it\'s a Doctrine entity']);
});
```
So the container already knows every entity FQCN at compile time, attribute already read.
1. add a dedicated tag (e.g. `doctrine.orm.entity`) in that same autoconfiguration hook (symfony/symfony side),
2. A compiler pass in DoctrineBundle collects the tagged FQCNs,
3. Feed them to a MappingDriver that takes a class list instead of directories,
4. Results are cached in the compiled container — zero runtime overhead.
This is the same way Symfony 7.4 used to auto-register controllers as routes (PR [#61492](https://github.com/symfony/symfony/pull/61492), `routing.controller` tag + `tagged_services`).
For BC, behind a new option:
```yml
doctrine:
orm:
auto_discover_entities: true # true by default on next major version
```
Edge cases
- Explicit mappings always win; discovered entities also covered by one are deduplicated.
- Discovered entities go to the default entity manager; multi-EM setups keep explicit mappings.
- Projects with a legacy exclude: `../src/Entity` in services.yaml are not scanned by the container: needs a documented migration note (drop the exclude, 7.3 handles it).
Contributor guide
Assessment
This issue has not been assessed yet.