Je suis cette recette http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/cookbook/blending-orm-and-mongodb-odm.html#event-subscriber
et quand j'arrive à l'abonné de l'événement je ne suis pas capable d'injecter le bon entity manager
celui qui est nommé $this->dm
initialisé dans le constructeur.
D'après ce que j'ai compris, le gestionnaire d'entités utilisé par l'entité en cours de chargement peut être récupéré par le biais de la fonction $em = $eventArgs->getEntityManager();
alors j'en ai besoin d'un autre que je inject
de la manière suivante :
services:
postload.listener:
class: myVendor\\myFooBarBundle\\Listener\\myEntityListener
tags:
- { name: doctrine.event\_listener, event: postLoad }
arguments:
- "@doctrine.orm.foobar\_entity\_manager"
Ce sont mes gestionnaires d'entités :
//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"
Quand injecting
le site foobar entity manager
En utilisant la stratégie ci-dessus, j'obtiens l'erreur suivante :
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".
C'est myVendor\myFooBarBundle\Listener\myEntityListener
classe :
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 );
}
}
}
Aussi pour éviter le circular reference error
J'ai essayé not
pour injecter le foobar entity manager
et le faire passer 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 );
}
}
}
Cette dernière mise en œuvre m'amène à l'erreur suivante :
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.
L'erreur ci-dessus est causée par $fooBarEntity = $eventArgs->getEntityManager('foobar')->getRepository( 'myVendor\myFooBarBundle\View\myFooBarEntity' )->findOneBy( array( 'id' => $myEntity->getFooBarEntityId() ) );
parce que lorsque je place echo 'hello';die() ; juste avant cette ligne, l'erreur n'est pas déclenchée, mais lorsqu'elle est placée juste après la ligne, l'erreur est déclenchée. hello
n'est pas indiqué. L'erreur me fait penser que, bien que je reçoive explicitement le message d'erreur de l'utilisateur, il n'y a pas de réponse. foobar
connexion par $eventArgs->getEntityManager('foobar')
il me donne toujours le default
connection/entity manager
.
Afin de revérifier myVendor\myFooBarBundle\View\myFooBarEntity
la syntaxe que je suis allé voir octrine\ORM\Mapping\Driver\DriverChain
et placé le code suivant :
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();
Ce code DriverChain me donne ce qui suit, c'est pourquoi je pense que la connexion 'foobar' n'est jamais utilisée ou que Symfony a une sorte de bug d'interprétation. orm.yml
qui définit les gestionnaires d'entités et les espaces de noms à utiliser.
classe : monVendeur \myFooBarBundle\View\myFooBarEntity
espace de noms : myVendor \myFooBarBundle\Entity bool(false)
Si je cherche le entity
mot à l'intérieur myVendor\myFooBarBundle\View\myFooBarEntity
Je viens de trouver @ORM\Entity
pour la définition de l'entité et aussi @ORM\OneToMany( targetEntity=.....)
pour la relation avec une autre entité.
J'espère que quelqu'un pourra m'aider, car cela me rend fou. Merci beaucoup !