Code Monkey home page Code Monkey logo

Comments (42)

Enchufadoo avatar Enchufadoo commented on July 2, 2024 14

Guys, do I have to register every repository manually or is there a way to register all repositories in the folder src/Repository?

Edit: figured it out

App\Repository\:
        resource: '../src/Repository'
        autowire: true
        tags: ['doctrine.repository_service']

from maker-bundle.

yceruto avatar yceruto commented on July 2, 2024 12

Hi @kironet, make sure your ColorRepository is registered and autowired into config/services.yaml file.

from maker-bundle.

fyrye avatar fyrye commented on July 2, 2024 9

@chriscadcw you need to override the __construct within the repository that extends ServiceEntityRepository. See: https://symfony.com/doc/4.0/doctrine.html#querying-for-objects-the-repository.

Extend ServiceEntityRepository and override the __construct()

src./Repository/YourEntityRepository.php

namespace App\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use App\Entity\YourEnity;
use Doctrine\Common\Persistence\ManagerRegistry;

class YourEntityRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
         parent::__construct($registry, YourEnity::class);
    }

   //....
}

src/Entity/YourEntity.php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\YourEntityRepository")
 */
class YourEntity
{
   //...
}

This is because ServiceEntityRepository by default requires an instance of ManagerRegistry $registry and string $entityClass as its arguments, which Symfony is unable to automatically provide. Resulting in the following exception:

Cannot autowire service "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository": argument "$entityClass" of method "__construct()" has no type-hint, you should configure its value explicitly.

By overriding the method to limit the arguments to only ServiceEntityRepository::__construct(ManagerRegistry $registry) Symfony will autowire the instance of ManagerRegistry and allow you to explicitly define the entity class name by calling parent::__construct($registry, YourEnity::class);.


Update for symfony/maker-bundle >= 1.16.0

Using the above example, instead of explicitly defining a FQCN for the repositoryClass, symfony/maker-bundle will use the ::class keyword of the repository when using make:entity [sic].

Please note that the below repositoryClass values are not wrapped in quotes!!!

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use App\Repository\YourEntityRepository;

/**
 * @ORM\Entity(repositoryClass=YourEntityRepository::class)
 */
class YourEntity
{
   //...
}

Supplying YourEntityRepository::class will translate to a FQCN string without the leading backslash as "App\Repository\YourEntityRepository", Example: https://3v4l.org/HG1dB

Alternatively you can manually supply the global namespace of the repository class.

/**
 * @ORM\Entity(repositoryClass=\App\Repository\YourEntityRepository::class)
 */

repositoryClass should not have a leading backslash \

The leading backslash conflicts with how Symfony generates and references service names when not using the ::class keyword, which can result in the following exception:

The "App\Repository\ColorRepository" entity repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could not be found. Make sure the service exists and is tagged with "doctrine.repository_service".

This issue appears to have been resolved sometime after Symfony 3.4 (looking for associated pull request)

Despite EntityManager::getRepository() working with or without the leading backslash, EntityManager::getRepository() auto-corrects the backslash implementation when creating the custom repository instance by using [sic]

new $repositoryClassName($entityManager, $metadata)

Example: https://3v4l.org/sYs16

However the repositoryClass is generated by make:entity and is only documented as a FQCN without the leading backslash in the Doctrine and Symfony documentation.

As explained in the PHP documentation for the ::class keyword, a FQCN does not begin with the global namespace separator (leading backslash). Which contradicts the Name resolution rules for Fully qualified name

::class Keyword Documentation [sic]

the class keyword is also used for class name resolution. You can get a string containing the fully qualified name of the ClassName class by using ClassName::class

from maker-bundle.

tacman avatar tacman commented on July 2, 2024 7

It's working for me after I clear and warmup the cache.

from maker-bundle.

huncwot avatar huncwot commented on July 2, 2024 5

Hi, I had simillar issue. In my case I had to change this (irrevelant code is removed):

<?php

namespace AppBundle\Entity;

use AppBundle\Repository\ImportRepository;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="ImportRepository")
 */
class Import implements ...

to this:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ImportRepository")
 */
class Import implements ...

and had to clear apcu cache.

from maker-bundle.

Aerendir avatar Aerendir commented on July 2, 2024 5

Reading the Tomas Votruba's post about "How to use Repository with Doctrine as Service in Symfony", he says that the annotation @Entity("Namespace\To\RepositoryClass") has to be removed as, if you don't, "you'd get a segfault error due to circular reference.".

So, I did simply this: removed the reference to repository in my entity, and all worked well again.

/**
- * @Entity(repositoryClass="App\Repository\PostRepository")
+ * @Entity
  */
 final class Post
 {
     ...
 }

from maker-bundle.

yceruto avatar yceruto commented on July 2, 2024 3

So I guess it was not auto tagged for some reason, are you using Symfony = 3.3+, right? autoconfigure: true? else, try the manual registration:

App\Repository\ColorRepository:
    tags: ['doctrine.repository_service']

from maker-bundle.

clem avatar clem commented on July 2, 2024 3

I think I found a solution. You have to add autowire: true in the repository declaration:

App\Repository\ColorRepository:
    autowire: true
    tags: ['doctrine.repository_service']

from maker-bundle.

Lpu8er avatar Lpu8er commented on July 2, 2024 2

@chriscadcw probably a bit late for you, but may help for future references.

This error is also usually obtained if you do not implement the __construct method while extending a ServiceEntityRepository. That means it's probably not related to the maker bundle repository, but more a Doctrine thing.

from maker-bundle.

BonBonSlick avatar BonBonSlick commented on July 2, 2024 2
  
services:
  # default configuration for services in *this* file
  _defaults:
    autowire: true      # Automatically injects dependencies in your services.
    autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
    public: false       # Allows optimizing the container by removing unused services; this also means
    # fetching services directly from the container via $container->get() won't work.
    # The best practice is to be explicit about your dependencies anyway.

  # makes classes in src/ available to be used as services
  # this creates a service per class whose id is the fully-qualified class name
  App\:
    resource: '../src/*'
    exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Traits,Utils,Kernel.php}'

  # controllers are imported separately to make sure services can be injected
  # as action arguments even if you don't extend any base controller class
  App\Controller\:
    resource: '../src/Controller'
    tags: ['controller.service_arguments']

App\Repository\RentalRepository:
    class: 'App\Repository\RentalRepository'
    autowire: true
    public: true
    tags: ['doctrine.repository_service']

Same error


........E                                                           9 / 9 (100%)

Time: 10.05 seconds, Memory: 50.25MB

There was 1 error:

1) App\Tests\Functional\RentalControllerTest::followSecondStepRedirectCorrectUrl

RuntimeException: The "\App\Repository\RentalRepository"
 entity repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could 
not be found. Make sure the service exists and is tagged with "doctrine.repository_service".
  • @Orm\Entity(repositoryClass="\App\Repository\RentalRepository")

fix, remove \

  • @Orm\Entity(repositoryClass=" here
    App\Repository\RentalRepository")

from maker-bundle.

Aerendir avatar Aerendir commented on July 2, 2024 2

To make things work "magically", you need to keep attention to some small things.

There are three possible ways to write entities and reporitories:

  1. Way 1: Indicate the repository class directly in the entity class
  2. Way 2: Indicate the entity class in the repository class
  3. Way 3: Indicate the linking between entity and its repository on both classes

Below the example codes.

Way 1: Indicate the repository class in the entity class

Docs: https://symfony.com/doc/current/doctrine.html#creating-an-entity-class

// src/Entity/MyEntity.php

namespace App\Entity;

/**
 * The entity class specifies which is its repository class.
 * NOTE: No leading backslash
 * @ORM\Entity(repositoryClass="App\Repository\MyEntityRepository")
 */
class MyEntity {
...
}

In this case the repository class is like this:

// src/Repository/MyEntityRepository.php

namespace App\Repository;

use Doctrine\ORM\EntityRepository;

final class MyEntityRepository extends EntityRepository
{
}

Note:

  1. The entity class uses the @Entity annotation to specify the repository class
  2. In this case the repository class extends EntityRepository
  3. You can use also a leading slash as FQNS, but this is not correct:
// src/Entity/MyEntity.php

namespace App\Entity;

/**
 * The entity class specifies which is its repository class.
- * @ORM\Entity(repositoryClass="App\Repository\MyEntityRepository")
+ * Using the leading backslash IS WRONG
+ * @ORM\Entity(repositoryClass="\App\Repository\MyEntityRepository")
 */
class MyEntity {
...
}

Way 2: Indicate the entity class in the repository class (Keep attention!)

In this case we invert the linking: now is the repository class that tells which is the class for which it is built.

The code is as the one below.

// src/Entity/MyEntity.php

namespace App\Entity;

/**
 * Now the entity has no information about its corresponding repository class.
 * @ORM\Entity
 */
class MyEntity {
...
}

In this case the repository class is like this:

// src/Repository/MyEntityRepository.php

namespace App\Repository;

use App\Entity\MyEntity;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

final class MyEntityRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        // Now is the repository class that tells to which entity it belongs to
        parent::__construct($registry, MyEntity::class);
    }
}

Note:

  1. The entity class doesn't pass anything to the @Entity annotation, anymore;
  2. The repository class specifies to which entity it belongs to;
  3. This works, but leads to some unwanted consequences when retrieving the repositories from the entity manager.

The docs of Symfony leaves this being understood when they say:

When you fetch your repository (i.e. ->getRepository(Product::class)), it is actually an instance of this object! This is because of the repositoryClass config that was generated at the top of your Product entity class.
https://symfony.com/doc/current/doctrine.html#querying-for-objects-the-repository

--> So, you should anyway indicate the repositoryClass in your entity (Way 3). <--

Way3: Creating the link on both classes, entity and repository

In entity class, instead of hardcoding the namespace, you need to use ::class suffix:

// src/Entity/MyEntity.php

namespace App\Entity;

use App\Repository\MyEntityRepository;

/**
 * The entity specify its own repository.
 * NOTE: No leading backslash
 * @ORM\Entity(repositoryClass="App\Repository\MyEntityRepository")
 */
class MyEntity {
...
}

and now you can also link the entity from the repository class

// src/Repository/MyEntityRepository.php

namespace App\Repository;

use App\Entity\MyEntity;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

final class MyEntityRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        // The repository specifies the entity to which it belongs to
        // NOTE: No leading backslash
        parent::__construct($registry, 'App\Entity\MyEntity');
    }
}

The (my own - unofficial) best practice: use ::class suffix (and prefer Way 3)

The real problem is the leading backslash (\App\...).

This may cause, above the other troubles, the error reported:

The "App\Repository\ColorRepository" entity repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could not be found. Make sure the service exists and is tagged with "doctrine.repository_service".

So, the best solution is to use the ::class suffix:

// src/Entity/MyEntity.php

namespace App\Entity;

use App\Repository\MyEntityRepository;

/**
 * The entity specify its own repository.
 * NOTE: THE REPOSITORY CLASS NAME IS NOT QUOTED!
 * @ORM\Entity(repositoryClass=MyEntityRepository::class)
 */
class MyEntity {
...
}

and now you can also link the entity from the repository class

// src/Repository/MyEntityRepository.php

namespace App\Repository;

use App\Entity\MyEntity;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

final class MyEntityRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        // The repository specifies the entity to which it belongs to
        parent::__construct($registry, MyEntity::class);
    }
}

Suggestion

Symfony should intercept a situation like this and alert that only one of the two ways should be used, or, at least, try to reconcile the linking between entities and repositories if possible.

Maybe a bug issue should be opened in Symfony repo, as the problem is of Symfony and not of the MakerBundle.

Note: read also #98 (comment) that was updated with some good explanations after a long discussion (now deleted) between @fyrye and me.

from maker-bundle.

weaverryan avatar weaverryan commented on July 2, 2024 1

It should “just work”. But check your services.yaml file to make sure that the Repository directory is not in the “exclude” for the App\ registration line. If you’re having issues, please post your services.yaml file :)

from maker-bundle.

tacman avatar tacman commented on July 2, 2024 1

from maker-bundle.

weaverryan avatar weaverryan commented on July 2, 2024 1

Hey @vladciulley!

I can probably help :). A few things:

  1. In your vendor bundle, you are 100% responsible for registering your services. What I mean is, nothing in the app's services.yaml file will have any effect on your services.

  2. Typically, it's not a best practice to use service auto-registration, autowiring or autoconfiguration in vendor bundles. To keep things predictable, you should really explicitly configure everything. You don't have to, but that's the best practice :).

  3. ONE way or another, you need to give your repository's the doctrine.repository_service tag. In an application, this just happens magically because of the services.yaml config. In a vendor bundle, it's your job. If you define the services explicitly, just be sure to give each repository service the tag. If you do want to use auto-registration, etc, then you should add the autoconfigure: true option when "loading" your services. You actually DID this in your final services.yaml example above. I don't know why this didn't work, but you're probably very close :). My recommendation (IF you're going to do the auto-registration stuff, is to just have ONE line that auto-registers everything) and have autoconfigure: true under it. I noticed that you first seem to auto-register everything, but omit the Repository classes. That may be causing some confusion, and you may be overriding some service definitions later with other auto-registration lines. If you simplify, then your autoconfigure: true may start working.

Cheers!

from maker-bundle.

carlospauluk avatar carlospauluk commented on July 2, 2024 1

Actually, there's this another way. Instead of extending ServiceEntityRepository, do extend EntityRepository. Then, create the constructor like this:

public function __construct(EntityManagerInterface $registry)`
{
        $entityClass = $this::getEntityClass();
        $classMetadata = $registry->getClassMetadata($entityClass);
        parent::__construct($registry, $classMetadata);
}

And in services.xml, declare the service like this:

<!-- FilterRepository -->
<service id="crosier_source.crosier_lib_base_bundle.repository.filter_repository"
         class="CrosierSource\CrosierLibBaseBundle\Repository\FilterRepository">
    <argument type="service" id="doctrine.orm.default_entity_manager"/>
    <tag name="doctrine.repository_service" />
</service>
<service id="CrosierSource\CrosierLibBaseBundle\Repository\FilterRepository"
         alias="crosier_source.crosier_lib_base_bundle.repository.filter_repository" />

Now the $this->getDoctrine()->getRepository(YourClass::class); works again.

from maker-bundle.

dsentker avatar dsentker commented on July 2, 2024 1

I had the same exception message:

The entity [...] repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could not be found. Make sure the service exists and is tagged with "doctrine.repository_service".

I thought it had something to do with my complex inheritance mapping. After hours, i found the solution:

I replaced this line:
* @ORM\Entity(repositoryClass="\App\Repository\AdRepository")
with
* @ORM\Entity(repositoryClass="App\Repository\AdRepository")
Note the (removed) backslash at the beginning. This is just a weird exception message.

* @ORM\Entity(repositoryClass="\I_DO_NOT_EXIST_App\Repository\AdRepository") throws

The "[...]" entity has a repositoryClass set to "\I_DO_NOT_EXIST_App\Repository[...]", but this is not a valid class. Check your class naming. If this is meant to be a service id, make sure this service exists and is tagged with "doctrine.repository_service".

But if i reference a valid FQ Repository class (again, with leading backslash, like ORM\Entity(repositoryClass="\App\Repository\AdRepository") ), the message is completely wrong or misleading, in my opinion. In other cases, a leading backslash is no problem and work fine (as expected):

/**
  * @var Address
  * @ORM\Embedded(class="\App\Entity\Utils\Address")
  */
  private $address;

from maker-bundle.

fyrye avatar fyrye commented on July 2, 2024 1

As a warning to others who found this page looking to resolve the exceptions mentioned in this thread when using the make:entity command in symfony/maker-bundle and implementing entity repositories as a Symfony service.

"Way 1" and "Way 2" examples above should not be used, as they will not resolve any issues mentioned in the other posts in this thread and not "make things work 'magically'". As the author did not provide any specifics as to how each example will impact your application, please see the below details for clarification.

"Way 1" will break repositories as a Symfony service functionality and is specifically the default custom repository configuration as documented by Doctrine. Permitting only the EntityManager::getRepository() custom repository functionality with and/or without the Symfony Framework.

"Way 2" will break the EntityManager::getRepository() functionality, by returning an instance of the default EntityRepository and not the expected custom repository. It was originally intended as an undocumented workaround for Symfony 3.3 environments, to enable repositories as a Symfony service that resulted in a circular reference exception, since the ServiceEntityRepository class was unavailable until Symfony 3.4 and doctrine/doctrine-bundle 1.8.


"Way 3" and "use :class: suffix" examples are safe to use and will function as intended with repositories as a Symfony service for dependency injection and EntityManager::getRepository() custom repositories. Both methods are how make:entity generates entities and repositories, depending on the version of symfony/maker-bundle installed.

"Way 3" is the method as documented by Symfony by using the make:entity command in symfony/maker-bundle 1.3 - 1.15.x.
There was a misunderstanding by others in this thread when manually supplying the global namespace separator (leading backslash) in the repositoryClass property, that caused a "service could not be found" exception to be thrown.

"use ::class suffix" example is the method currently employed by the make:entity command in symfony/maker-bundle 1.16.0 and later
It serves to resolve any ambiguity with the leading backslash usage in the repositoryClass property. Resulting in the same functionality as "Way 3".

from maker-bundle.

PayteR avatar PayteR commented on July 2, 2024

Could you @yceruto please provide an example? Thank you.

from maker-bundle.

PayteR avatar PayteR commented on July 2, 2024

hm, it's not in excluded

    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,Migrations,Tests}'

from maker-bundle.

PayteR avatar PayteR commented on July 2, 2024

i'm using Symfony 4.0.3 with flex bootstraped just recently, @weaverryan said that it should be automatic, so somewhere is problem and it would be better to solve it rather in Symfony bundles, than do some quick fixes in my project. Here is my whole services.yaml, i can provide anything that could help, just let me know.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,Migrations,Tests}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones

from maker-bundle.

clem avatar clem commented on July 2, 2024

Same problem here... :(

from maker-bundle.

stof avatar stof commented on July 2, 2024

I think I found a solution. You have to add autowire: true in the repository declaration:

@clem that's weird, as the services.yaml of a Flex project already enables autowiring as a file-level default. Have you changed this ?

from maker-bundle.

clem avatar clem commented on July 2, 2024

@stof No, but I think my error was to set this services in an external file without adding the _defaults at the beginning of the file. That's why I found this solution.

from maker-bundle.

PayteR avatar PayteR commented on July 2, 2024

@tacman i tried this, but didn't helped, did you update something prior warmup or did something that could fix problem meanwhile?

from maker-bundle.

kironet avatar kironet commented on July 2, 2024

Just to be clear, I've never found a solution that'd fixed this error. Just went back to old fashion repository file.
My config is the same as everybody else's, and I really don't want to declare every shingle one repository in my services. :)

from maker-bundle.

continga avatar continga commented on July 2, 2024

I am having the same issue with a bare new Symfony 4 application - is there any bugfix or workaround available yet? Manually adding the repository class to the services.yaml file did not help

from maker-bundle.

continga avatar continga commented on July 2, 2024

Okay, some more information:

The error only happens for me when I request a repository directly via Doctrine's EntityManager, so e.g. inside of a controller by $this->getDoctrine()->getManager()->getRepository(MyEntity::class).

The error does not happen when I let the service container inject the repository into my service e.g. like this:

/**
 * @required
 */
public function setRepo(MyRepo $repo)
{
    $this->repo = $repo;
}

I am then able to access the repository directly via $this->repo and everything works.

So the error seems to be related to the Doctrine EntityManager?

from maker-bundle.

weaverryan avatar weaverryan commented on July 2, 2024

@continga: that’s interesting. What is the error you get exactly? Can you post your services.yaml file, your entity and your repository? And what version of DoctrineBundle do you have?

Enough people are having issues that it seems like there’s an issue, or that something is too easy to mess up.

from maker-bundle.

vladciulley avatar vladciulley commented on July 2, 2024

@weaverryan, I'm having a related issue on Symfony 4.0.8. Might be the same so I'll write it here.

I'm working on a bundle structured like this:

\Acme
  \FooBundle
    \Bar
      \Entity
        - Bar.php
      \Repository
        - BarRepository.php
      - BarManager.php
    \Baz
      \Entity
        - Baz.php
      \Repository
        - BazRepository.php
      - BazManager.php
    \Resources
        \config
            - services.yaml

the bundle services configuration:

# vendor\acme\foo-bundle\Resources\config\services.yaml
services:
    Acme\FooBundle\:
        resource: '../../*/{*Manager.php,Repository/*Repository.php}'
        autowire: true

In project's services I have:

# config\services.yaml
services: 
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

With this configuration, when using in controller (just as @continga said in latest answer):
$this->getDoctrine()->getRepository(Bar::class)
or
$this->getDoctrine()->getManager()->getRepository(Bar::class),
it throws an error:

The "Acme\FooBundle\Bar\Repository\BarRepository" entity repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could not be found. Make sure the service exists and is tagged with "doctrine.repository_service".

In console, if I run:

php bin/console debug:autowiring | grep BarRepository

I get:

Acme\FooBundle\Bar\Repository\BarRepository

Adding this in bundle config:

# vendor\acme\foo-bundle\Resources\config\services.yaml
Acme\FooBundle\Bar\Repository\BarRepository\:
    resource: '../../Bar/Repository/BarRepository.php'
    autowire: true
    tags: ['doctrine.repository_service']

before or after the Acme\FooBundle\: config, does not help (It's pretty difficult to disable the original config to see if it makes any difference, since there are many services interconnected in the project).

Tried to force the tags registration, according to the documentation: https://symfony.com/doc/current/service_container/tags.html#autoconfiguring-tags

by using:

protected function build(ContainerBuilder $container)
{
    $container->registerForAutoconfiguration(BarRepository::class)
        ->addTag('doctrine.repository_service')
    ;
}

Tried to put the build() method in my bundle class, then in kernel and even in my bundle's extension class (as suggested in the documentation - which I think is wrong), but it just won't work!

from maker-bundle.

chriscadcw avatar chriscadcw commented on July 2, 2024

Hello,

So I just ran into this same issue, and I wasn't sure if bumping an old post is the correct thing to do or whether I should create a new one for the same issue.

The error:

The "\App\Repository\MailTemplateRepository" entity repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could not be found. Make sure the service exists and is tagged with "doctrine.repository_service".

From what I've been able to determine, it is caused by either calling a repository directly, or trying to TypeHint an Entity in a method:

public function show(MailTemplate $mailTemplate): Response
    {
        return $this->render('mail_template/show.html.twig', ['mail_template' => $mailTemplate]);
    }

and

public function show($id): Response
    {
        $mailTemplate = $this->getDoctrine()->getManager()->getRepository (MailTemplate::class)->find($id);
        return $this->render('mail_template/show.html.twig', ['mail_template' => $mailTemplate]);
    }

both generate the error, however,

public function show(MailTemplateRepository $mailTemplateRepository, $id): Response
    {
        $mailTemplate = $mailTemplateRepository->find ($id);
        return $this->render('mail_template/show.html.twig', ['mail_template' => $mailTemplate]);
    }

Does not cause the error.

Some files that may be helpful:
composer.json

{
    "type": "project",
    "license": "proprietary",
    "require": {
        "php": "^7.1.3",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "jms/serializer": "^1.12",
        "knplabs/knp-menu-bundle": "^2.0",
        "sensio/framework-extra-bundle": "^5.2",
        "symfony/asset": "^4.1",
        "symfony/config": "^4.1",
        "symfony/console": "^4.1",
        "symfony/flex": "^1.0",
        "symfony/form": "^4.1",
        "symfony/framework-bundle": "^4.1",
        "symfony/lts": "^4@dev",
        "symfony/orm-pack": "^1.0",
        "symfony/security-bundle": "^4.1",
        "symfony/swiftmailer-bundle": "^3.2",
        "symfony/twig-bundle": "^4.1",
        "symfony/validator": "^4.1",
        "symfony/webpack-encore-pack": "^1.0",
        "symfony/yaml": "^4.1"
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.0",
        "symfony/dotenv": "^4.1",
        "symfony/maker-bundle": "^1.5",
        "symfony/profiler-pack": "^1.0",
        "symfony/web-server-bundle": "^4.1"
    },
    "config": {
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "replace": {
        "symfony/polyfill-ctype": "*",
        "symfony/polyfill-iconv": "*",
        "symfony/polyfill-php71": "*",
        "symfony/polyfill-php70": "*",
        "symfony/polyfill-php56": "*"
    },
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    },
    "conflict": {
        "symfony/symfony": "*"
    },
    "extra": {
        "symfony": {
            "allow-contrib": false
        }
    }
}

config/services.yaml

# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
    locale: 'en'
    app.name: 'S.A.V.E. Online Assessment'

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

    # adding the required tag to all repository services
    App\Repository\:
        resource: '../src/Repository'
        autowire: true
        tags: ['doctrine.repository_service']

    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones
    app.menu_builder:
        class: App\Helper\MenuBuilder
        arguments: ["@knp_menu.factory"]
        tags:
            - { name: knp_menu.menu_builder, method: createMainMenu, alias: main }
            - { name: knp_menu.menu_builder, method: createAdminMenu, alias: admin }
            - { name: knp_menu.menu_builder, method: createAccountMenu, alias: account }
            - { name: knp_menu.menu_builder, method: createClientMenu, alias: client }

While this work around does allow you to use the repositories in your controllers, I don't believe it was intended to be the only way you could use repositories.

Any feedback would be great.

from maker-bundle.

chriscadcw avatar chriscadcw commented on July 2, 2024

@huncwot Thank you for your response, however, it is not the repository class that is causing the issue, it is in fact the Doctrine ServiceEntityRepository class that is causing it to break.

To test this I added the following code to my service.yaml file to see if I could manually autowire the missing service dependency.

# Tagging the doctrine ServiceEntityRepository for implementation in classes
Doctrine\Bundle\DoctrineBundle\Repository\:
    resource: '../vendor/doctrine/doctrine-bundle/Repository'
    autowire: true
    tags: ['doctrine.repository_service']

The results were the following error:

Cannot autowire service "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository": argument "$entityClass" of method "__construct()" has no type-hint, you should configure its value explicitly.

I don't know exactly what to do to fix this, and this particular issue is being caused by including an EntityType form field that is doing it's own query.

Any ideas on how to fix this issue, I have a client who is waiting for me to finish updating their site and at this point I'm having to start looking at alternatives.

from maker-bundle.

PFranciscoRojas avatar PFranciscoRojas commented on July 2, 2024

It's working for me after I clear and warmup the cache.

It also worked for me.

from maker-bundle.

carlospauluk avatar carlospauluk commented on July 2, 2024

Same here. With autowiring in a controller constructor (or via a setter with @required) it does not complain about the ServiceEntityRepositoryInterface not being a service. But with doctrine->getRepo it does.

For now, I'll be using the autowiring approach.

from maker-bundle.

skydiablo avatar skydiablo commented on July 2, 2024
/**
 * Class FooEntity
 * @ORM\Entity(repositoryClass="App\Repository\FooRepository")
 */
class FooEntity
{
...
}

in my case the solution was easy, just remove the \ prefix for repositoryClass annotation.

EDIT: oh #98 (comment) already got it ;)

from maker-bundle.

MichaelBrauner avatar MichaelBrauner commented on July 2, 2024

I had the same problem.
Just change
* @ORM\Entity(repositoryClass="App\Entity\Repository\TeachingEventRepository")
to
* @ORM\Entity(repositoryClass="App\Repository\TeachingEventRepository")
AND dont forget - to move the file :D !

from maker-bundle.

nuryagdym avatar nuryagdym commented on July 2, 2024

In my case was also because of the wrong @entity annotation:
@ORM\Entity(repositoryClass="DefinitionRepository")
when I changed it to :
@ORM\Entity(repositoryClass="App\Repository\DefinitionRepository")
it worked

from maker-bundle.

salmansheikh5 avatar salmansheikh5 commented on July 2, 2024

@kironet Make sure your repository file is named properly. For Example, it should be named:
App\Repository\ColorRepository not App\Repository\Color because that is the name of the entity. It is not a FQCN. Oh and don't forget to rename the PHP file too. That is, ColorRepository.php

from maker-bundle.

drupol avatar drupol commented on July 2, 2024

Sorry to dig up old topics, but I just submitted this: #887 , it might be helpful for some people here as it doesn't require to tag repositories anymore.

Let me know what you think!

from maker-bundle.

jzohrab avatar jzohrab commented on July 2, 2024

Old topic that just bit me now. I had implemented one class and repo, and then had another that was almost identical, so I just copied the files and edited them to the new class name, because I'm lazy. It took some time to find this solution, and then several cache clears and warms, and rm -rf var/cache, to clear it out.

It appears that there are a few common reasons for this error - (slash in repo fqdn, and cacheing) - perhaps the error message could be beefed up to suggest common solutions, or a link to a canonical knowledge base, so that newer people like me don't go down the rabbit hole of finding trusted sources.

from maker-bundle.

kosmodisk avatar kosmodisk commented on July 2, 2024

Cache clear helped me too, only that I needed to add --env=test too.

from maker-bundle.

rtwent avatar rtwent commented on July 2, 2024

My five cents.
I have SomeRandomnameRepository, but somebody put such kind of annotation (attention to camelCase: RandomName and Randomname):

@ORM\Entity(repositoryClass="App\Repository\SomeRandomNameRepository")

from maker-bundle.

jrushlow avatar jrushlow commented on July 2, 2024

Closing - this issue originated in 2017 on Symfony 3.x. If anyone is experiencing problems, please create a new issue with the exact error message they're using and the steps to reproduce the error.

Try running bin/console cache:clear before creating an issue to see if this solves the problem. Often times, dev or test cache can cause problems in local apps under development.

from maker-bundle.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.