Mongodb-odm: references class "Doctrine\ODM\MongoDB\UnitOfWork" but no such service exists.

Created on 27 Jun 2018  路  11Comments  路  Source: doctrine/mongodb-odm

I,
when i try to use injection dependency into a controller in Symfony4 i have this error :

Cannot autowire service "App\Repository\UserRepository": argument "$uow" of method "Doctrine\ODM\MongoDB\DocumentRepository::__construct()" references class "Doctrine\ODM\MongoDB\UnitOfWork" but no such service exists.

My dependency is a Service (UserService) who has a repository injection (UserRepository). This UserRepository extends DocumentRepository.
Is it normal because i found a solution but may be i make mistake ?
Thank

Most helpful comment

@libressence It's not about not being able to use the injection to other services/controllers, it's about the autowiring (which basically means Symfony detects that only 1 service of a particular class exists and automatically assumes it's the correct one. Or more accurately, service is named exactly as the class you're requesting to inject).

Here's a sample that should be helpful:

App\Repository\UserRepository:
    factory: ["@doctrine_mongodb", getRepository]
    # class: App\Repository\UserRepository # Note that this can be omitted since classname equals service name, which is what we want
    arguments: # Note that this argument is passed to factory method (getRepository) not the service instance
      - App\Document\User

Then you can use the injection/autowiring feature in other services/controller methods (if your Symfony is configured to do so).

All 11 comments

I think this is still the state of autowiring, https://github.com/doctrine/DoctrineMongoDBBundle/issues/443#issuecomment-385347539.

@SenseException is right, closing as autowiring stuff is specific to Symfony bundle and as such needs to be implemented there.

Ok, for me i want use autowiring for injecting service easly. I add that to my services.yml :

` mongodb.odm.unit_of_work:
class: Doctrine\ODM\MongoDB\UnitOfWork
autowire: true
Doctrine\ODM\MongoDB\UnitOfWork: '@mongodb.odm.unit_of_work'

mongodb.odm.mapping.class_metadata:
    class: Doctrine\ODM\MongoDB\Mapping\ClassMetadata
    autowire: true
    arguments:
        $documentName: 'StdClass'
Doctrine\ODM\MongoDB\Mapping\ClassMetadata: '@mongodb.odm.mapping.class_metadata'

mongodb.common.event_manager:
    class: Doctrine\Common\EventManager
    autowire: true
Doctrine\Common\EventManager: '@mongodb.common.event_manager'

mongodb.odm.hydrator_factory:
    class: Doctrine\ODM\MongoDB\Hydrator\HydratorFactory
    autowire: true
    arguments:
        $hydratorDir: '/var/cache/dev/doctrine/odm/mongodb/Hydrators'
        $hydratorNs: 'App\Hydrator'
        $autoGenerate: 1
Doctrine\ODM\MongoDB\Hydrator\HydratorFactory: '@mongodb.odm.hydrator_factory'`

And that work

@libressence I'm pretty sure you're better of aliasing existing Symfony/DoctrineODM services instead of recreating them. What you've done is error prone and will probably result in issues further down the road.

@libressence at a glance this seems like a bad idea. For instance the EventManager you have created manually will not be the same as the one DocumentManager is using internally, so it won't have same listeners subscribed to events. ClassMetadata is also wrong, usually there is no point in having one that maps \stdClass. All in all you should use factory notation for services and get their instances from DocumentManager to ensure consistency:

mongodb.common.event_manager:
    class: Doctrine\Common\EventManager
    factory: ['@ref_to_your_dm', 'getEventManager']
Doctrine\Common\EventManager: '@mongodb.common.event_manager'

I can't recall if it's true for all services but many of them will already be available in the Container so you will only need to alias interfaces:

Doctrine\Common\EventManager: '@doctrine_prolly_has_event_manager_registered`.

For their name please consult command like debug:container in your application.

Ok, thank @malarzm and @Steveb-p i will do it ! Hope that will work :)

If i can has a complete example for it work, that will be very great ! Because i search how to do what you say @malarzm but i don't understand exactly. Impossible to use mongodb on symfony for now

It's not impossible to use ODM with Symfony, it's just not possible to use autowiring. Use old way of mapping services and you'll be fine, here's chapter on factories.

Ok @malarzm :). I know it's possible, i just wanted to use new injection service system of symfony.
But ok... I will not use this for the moment...
Thank

@libressence It's not about not being able to use the injection to other services/controllers, it's about the autowiring (which basically means Symfony detects that only 1 service of a particular class exists and automatically assumes it's the correct one. Or more accurately, service is named exactly as the class you're requesting to inject).

Here's a sample that should be helpful:

App\Repository\UserRepository:
    factory: ["@doctrine_mongodb", getRepository]
    # class: App\Repository\UserRepository # Note that this can be omitted since classname equals service name, which is what we want
    arguments: # Note that this argument is passed to factory method (getRepository) not the service instance
      - App\Document\User

Then you can use the injection/autowiring feature in other services/controller methods (if your Symfony is configured to do so).

ok, sorry for my small level :). Now that work with your example @Steveb-p !
Many Thank !

Was this page helpful?
0 / 5 - 0 ratings