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!!