What about the drawbacks about the ServiceEntityRepository?
https://symfony.com/doc/current/doctrine/multiple_entity_managers.html
One entity can be managed by more than one entity manager. This
however results in unexpected behavior when extending from
ServiceEntityRepository in your custom repository. The
ServiceEntityRepository always uses the configured entity manager for
that entity.
In order to fix this situation, extend EntityRepository instead and no
longer rely on autowiring:
In an own project I've seen that using:
$repository = $entityManager->getRepository(MyEntity:class)
The $repository->_em
is not equals to $entityManager
(with both using the same connection), causing problems like:
$entity = $entityManager->getRepository(MyEntity:class)->find($id);
$entityManager->refresh($entity); // throws 'entity is not managed'
That's why the entity is fetched with $repository->_em
and the refresh (or persist, flush, etc.) is using $entityManager
.
This problem is described here:
https://github.com/symfony/symfony-docs/issues/9878
So... You can't rely in ServiceEntityRepository
using multiple entity managers, but the EntityRepository
doesn't allow autowire, so, what?
My two cents (I believe this should be works in every scenario):
Manually set the class metadata (something like you need to do in the constructor of the ServiceEntityManager
), so I can:
Remove the autowire of repositories in services.yaml:
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Repository,Tests,Kernel.php,Client}'
(you also add the repositories below in services.yaml
)
And create another /config/packages/repositories.yaml
and add:
my.entity.metadata:
class: App\Entity\Metadata
arguments:
$entityName: App\Entity\MyEntity
App\Repository\MyEntityRepository:
arguments:
[$class: my.entity.metadata]
Now you have a EntityRepository
that is capable of being autowireable. You can make a repositories.yaml file in the config and keep updated when you create/edit/delete your repositories. Is not cleanest but it should be works.