In Sylius 1.11, after creating a new Campaign
entity using the maker bundle, I get this error when trying to fetch a campaign using its repository:
Cannot autowire service "App\Repository\CampaignRepository": argument "$class" of method "Doctrine\ORM\EntityRepository::__construct()" references class "Doctrine\ORM\Mapping\ClassMetadata" but no such service exists.
This seems to be the code that trigger the error:
<?php
namespace App\Controller;
use App\Repository\CampaignRepository;
class CampaignController extends AbstractController {
protected CampaignRepository $repository;
public function __construct(CampaignRepository $repository) {
$this->repository = $repository;
}
public function details(string $id)
{
$campaign = $this->repository->find($id);
dd($campaign);
}
}
The App\Repository\CampaignRepository
exists and is defined as follow, which is what the Sylius documentation recommends:
<?php
namespace App\Repository;
use App\Entity\Campaign;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
/**
* @extends ServiceEntityRepository<Campaign>
*
* @method Campaign|null find($id, $lockMode = null, $lockVersion = null)
* @method Campaign|null findOneBy(array $criteria, array $orderBy = null)
* @method Campaign[] findAll()
* @method Campaign[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CampaignRepository extends EntityRepository
{
}
How to fix this error?
It turns out Sylius is quite picky on both the type hinting and the variable name. This is due to how Symfony's dependency injection works and how Sylius chose to use it.
Change the constructor to:
public function __construct(
\Sylius\Component\Resource\Repository\RepositoryInterface $campaignRepository
) {
$this->repository = $campaignRepository;
}
You need to use the bin/console debug:container
command. But if you try, you'll run into the same error message as when running you controller action.
What you need to do is:
App\Controller\CampaignController::__construct()
method)bin/console debug:container CampaignRepository
bin/console debug:container CampaignRepository
Select one of the following services to display its information:
[0] App\Repository\CampaignRepository
[1] Doctrine\Persistence\ObjectRepository $campaignRepository
[2] Doctrine\Common\Collections\Selectable $campaignRepository
[3] Sylius\Component\Resource\Repository\RepositoryInterface $campaignRepository
[4] Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository $campaignRepository
[5] Doctrine\ORM\EntityRepository $campaignRepository
Sylius\Component\Resource\Repository\RepositoryInterface $campaignRepository
but any of the suggestions with a parameter name should work)If you're curious how this works, have a look here: https://symfony.com/doc/current/service_container/autowiring.html#dealing-with-multiple-implementations-of-the-same-type