11

Why do I need to extend ServiceEntityRepository in my repository? In Symfony 3.4, I always extended EntityRepository. With ServiceEntityRepository I have a strange problem described here Symfony 4. InheritanceType("JOINED") and ParamConverter. Strange phenomenon

olek07
  • 513
  • 2
  • 7
  • 21

2 Answers2

13

You don't need to extend ServiceEntityRepository, but you should. Why? Because it allows you to use autowiring (which is a big enhancement in SF4 and a pleasure to develop with)

class ProductRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Product::class);
    }
}

Then you can use autowiring everywhere for example:

// From product controller
public function show(?int $id, ProductRepository $repository)
{
    $product = $repository->find($id);
    if (!$product) {
        throw $this->createNotFoundException(
            'No product found for id '.$id
        );
    }

    return new Response('Check out this great product: '.$product->getName());
}

If you don't want, no worries just use the old way:

// From product controller
public function show(?int $id, EntityManagerInterface $manager)
{
    $product = $manager->getRepository(Product::class)->find($id);
    // or this one but only in a controller which extend AbstractController
    $product = $this->getDoctrine()->getRepository(Product::class)->find($id);
    if (!$product) {
        throw $this->createNotFoundException(
            'No product found for id '.$id
        );
    }

    return new Response('Check out this great product: '.$product->getName());
}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
GuillaumeL
  • 509
  • 3
  • 14
  • Thank you. Your solution saved a lot time. If you try using without autowiring, you have to call method **findBy[EntityProperty]**. Otherwise, you get **"Symfony entity has no field _X_. You can therefore not call _findByX_ on entities repository"** error. With auto wiring you can call your method whatever you want – Ilyas Mar 11 '21 at 13:59
1

I came across this when I asked the same question while watching a training video on Symfony 4. (I also took a stab at your actual problem there.)

From what I can see of the code, you don't need to use the newer ServiceEntityRepository class, but it is an improvement. All it's doing is wrapping the EntityRepository class with a modified constructor, making the arguments you need to pass in a little friendlier for the developer, and taking advantage of autowiring.

As an example, I have manually wired up my custom repositories (extending EntityRepository) in Symfony version 3 with code like this in my services.yml file:

Fully\Qualified\Namespace\MyCustomRepository:
        factory: ["@doctrine.orm.entity_manager", getRepository]
        arguments: [Fully\Qualified\Namespace\Entity\MyEntity]

With the newer ServiceEntityRepository class, and version 4's enhanced autowiring, I can eliminate all of those manual wiring jobs, and let the Service Container do the job.

beltouche
  • 731
  • 6
  • 15