i'm following that recipe http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/cookbook/blending-orm-and-mongodb-odm.html#event-subscriber
and when i get to the event subscriber i'm not able to inject the proper entity manager
, the one named $this->dm
initialized in the constructor.
As i understand, the entity manager used by the entity which is being loaded can be retrieved through $em = $eventArgs->getEntityManager();
then i need another one which i inject
in the following manner:
services: postload.listener: class: myVendor\myFooBarBundle\Listener\myEntityListener tags: - { name: doctrine.event_listener, event: postLoad } arguments: - "@doctrine.orm.foobar_entity_manager"
Those are my entity managers:
//orm.yml orm: entity_managers: default: connection: default mappings: myVendormyFooBarBundle: prefix: "myVendor\myFooBarBundle\Entity" type: annotation is_bundle: true dir: "Entity" foobar: connection: foobar mappings: myVendormyFooBarBundle: prefix: "myVendor\myFooBarBundle\View" type: annotation is_bundle: true dir: "View"
When injecting
the foobar entity manager
using the above strategy i get the following error:
Circular reference detected for service "postload.listener", path: "routing.loader -> routing.db.loader -> doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> postload.listener -> doctrine.orm.fooba_entity_manager -> doctrine.dbal.foobar_connection".
That's myVendor\myFooBarBundle\Listener\myEntityListener
class:
class myFooBarEntityListener { public function __construct( \Doctrine\ORM\EntityManager $em ) { $this->em = $em; } public function postLoad( LifecycleEventArgs $eventArgs ) { $myEntity = $eventArgs->getEntity(); if( $myEntity instanceof \myVendor\myFooBarBundle\Entity\myEntity ) { $em = $eventArgs->getEntityManager(); $fooBarReflProp = $em->getClassMetadata( 'myVendor\myFooBarBundle\Entity\myEntity' )->reflClass->getProperty( 'FooBarEntity' ); $fooBarReflProp->setAccessible( true ); $fooBarEntity = $this->em->getRepository( 'myVendor\myFooBarBundle\View\myFooBarEntity' )->findOneBy( array( 'id' => $myEntity->getFooBarEntityId() ) ); $fooBarReflProp->setValue( $myEntity, $fooBarEntity ); } } }
Also to avoid the circular reference error
i've tried not
to inject the foobar entity manager
and get it through LifecycleEventArgs $eventArgs
:
class myFooBarEntityListener { public function postLoad( LifecycleEventArgs $eventArgs ) { $myEntity = $eventArgs->getEntity(); if( $myEntity instanceof \myVendor\myFooBarBundle\Entity\myEntity ) { $em = $eventArgs->getEntityManager(); $fooBarReflProp = $em->getClassMetadata( 'myVendor\myFooBarBundle\Entity\myEntity' )->reflClass->getProperty( 'FooBarEntity' ); $fooBarReflProp->setAccessible( true ); //NOTICE HOW HERE I SHOULD GET THE PROPER ENTITY MANAGER THROUGH $eventArgs $fooBarEntity = $eventArgs->getEntityManager('foobar')->getRepository( 'myVendor\myFooBarBundle\View\myFooBarEntity' )->findOneBy( array( 'id' => $myEntity->getFooBarEntityId() ) ); $fooBarReflProp->setValue( $myEntity, $fooBarEntity ); } } }
That last implementation throughs me the following error:
An exception has been thrown during the rendering of a template ("Class myVendor\myFooBarBundle\View\myFooBarEntity is not a valid entity or mapped super class.") in "SonataAdminBundle:CRUD:base_list.html.twig" at line 28.
The above error is caused by $fooBarEntity = $eventArgs->getEntityManager('foobar')->getRepository( 'myVendor\myFooBarBundle\View\myFooBarEntity' )->findOneBy( array( 'id' => $myEntity->getFooBarEntityId() ) );
because when i place echo 'hello';die(); just before that line the error is not thrown but when placed just after the line the error is thrown and hello
is not shown. The error makes me think that although i'm explicitly getting the foobar
connection through $eventArgs->getEntityManager('foobar')
it is still giving me the default
connection/entity manager
.
In order to double check myVendor\myFooBarBundle\View\myFooBarEntity
syntax i went to octrine\ORM\Mapping\Driver\DriverChain
and placed the following code:
if( strpos( $className, 'myFooBarEntity' ) ) { echo 'Class: '.$className."\n\n"; foreach ($this->_drivers as $namespace => $driver) { echo 'namespace: '.$namespace."\n"; $bool = strpos($className, $namespace); var_dump($bool); echo "\n\n"; } } die();
That DriverChain code gives me the following, that's why i think 'foobar' connection is never used or symfony has some kind of bug interpreting orm.yml
file which defines the entity managers plus namespaces to use.
class: myVendor\myFooBarBundle\View\myFooBarEntity
namespace: myVendor\myFooBarBundle\Entity bool(false)
If i look foor the entity
word inside myVendor\myFooBarBundle\View\myFooBarEntity
i just find @ORM\Entity
for the entity definition and also @ORM\OneToMany( targetEntity=.....)
for the relation with another entity.
I hope someone can help, as it's driving me crazy. Thanks a lot!!