doctrine / doctrine/DoctrineBundle

Auto-discover entities based on attribute

Open
#2,124 3 comments 4 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.