2012-03-02 5 views
2

私はそのレシピhttp://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/cookbook/blending-orm-and-mongodb-odm.html#event-subscriberに従っています。イベントのサブスクライバには、適切なentity managerを注入できません。$this->dmという名前のコンストラクタが初期化されています。私は理解するようSymfony2/Doctrine2:リスナーの中の複数のエンティティマネージャを管理する問題

$em = $eventArgs->getEntityManager();介して取得することができるロードされているエンティティによって使用されるエンティティマネージャは、私は別のものを必要とするどのI次のようにinject:これらは私のエンティティマネージャである

 
    services: 
     postload.listener: 
     class: myVendor\myFooBarBundle\Listener\myEntityListener 
     tags: 
      - { name: doctrine.event_listener, event: postLoad } 
     arguments: 
      - "@doctrine.orm.foobar_entity_manager" 

:私は次のエラーを取得する上での戦略を使用して

 
//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" 

injectingfoobar entity manager

また
 
    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); 
      } 
     } 
    } 

私はfoobar entity managerを注入するnotを試してみたcircular reference errorを避け、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); 
      } 
     } 
    } 

ことmyVendor\myFooBarBundle\Listener\myEntityListenerクラスです

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". 

エラー:

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.

上記のエラーは$fooBarEntity = $eventArgs->getEntityManager('foobar')->getRepository('myVendor\myFooBarBundle\View\myFooBarEntity')->findOneBy(array('id' => $myEntity->getFooBarEntityId()));によって引き起こされます。なぜなら、私がecho 'hello'; die();その行の直前にエラーはスローされませんが、行の直後に配置するとエラーがスローされ、helloは表示されません。エラーは、私が明示的にfoobar接続を$eventArgs->getEntityManager('foobar')経由で取得しているにもかかわらず、まだ私にdefaultconnection/entity managerを与えていると思うようになります。 i「はfoobarの」接続が使用されていないか、symfonyは持っているんだと思う理由です

 
    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(); 

DriverChainコードは私に次のことを与え、:

私はoctrine\ORM\Mapping\Driver\DriverChainに行って、次のコードを配置myVendor\myFooBarBundle\View\myFooBarEntity構文を再確認するためにエンティティマネージャと使用する名前空間を定義するファイルorm.ymlを解釈する何らかの種類のバグ。

クラス:myVendor \ myFooBarBundle \ビュー\ myFooBarEntity

名前空間:myVendor \ myFooBarBundle \エンティティ ブール値(false)を

私はmyVendor\myFooBarBundle\View\myFooBarEntityentity単語をfoor見れば私はちょうどのため@ORM\Entityを見つけます他のエンティティとの関係については@ORM\OneToMany(targetEntity=.....)である。

誰かが助けてくれることを願っています。それは私を狂ってしまいます。どうもありがとう!!あなたがで作業しているのEntityManagerによって管理されていないEntitesで動作するようにしようとしている

答えて

1

は、私はあなたの問題を参照してくださいと思います。

あなたの最初の例では、あなたはdoctrine.orm.foobar_entity_managerというサービスで働いています。つまり、myVendor\myFooBarBundle\Entityのエンゲージを認識していません。

第2のものでは、$eventArgs->getEntityManager('foobar')を使用して異なるentityManagersにアクセスしようとしますが、これは機能しません。 EventArgsは1つのentityManagerにのみ接続され、別のものにアクセスするための引数(foobarなど)はありません。

だから私はここを参照してください最良の解決策は、あなたの最初のアイデアでのように行動することですが、両方entityMangersを注入:

services: 
    postload.listener: 
    class: myVendor\myFooBarBundle\Listener\myEntityListener 
    tags: 
     - { name: doctrine.event_listener, event: postLoad } 
    arguments: 
     - "@doctrine.orm.default_entity_manager" 
     - "@doctrine.orm.foobar_entity_manager" 

あなたは循環依存関係の検出を持っている場合は、インスタンスであるdoctrineサービスを、注入しようSymfony\Bridge\Doctrine\ManagerRegistry

+0

はどうもありがとうを。私はすでに、両方のエンティティマネージャを注入し、サービスコンテナを注入してからドクトリンサービスを取得し、ドクトリンサービスを注入してから両方のエンティティマネージャを取得しましたが、私は常に循環参照エラーを取得しています。他に何ができるのか知っていますか?先生に感謝します:) – user846226

+0

最後に私は 'l3pp4rd DoctrineBehaviours'を見て、彼の構造に基づいてより高度なリスナを作成し、' doctrine'サービスから両方の接続を取得するのに問題はありませんでした。 – user846226

+0

これらの回答のいずれかが受け入れられたとマークされているか、少なくともあなたの解決策が投稿されていますか、@ user846226?前もって感謝します。 – webDEVILopers

2

私は解決策が見つかりました:あなたは今、いくつかのエンティティマネージャを使用することができます

namespace myVendor\myFooBarBundle\Listener\myEntityListener; 

use Symfony\Bundle\DoctrineBundle\Registry; 

class myFooBarEntityListener 
{ 

    private $reg; 

    public function __construct(Registry $reg) 
    { 
     //dont't put your entitymanager otherwise a loop appear during creation 
     $this->reg = $reg; 
    } 

    public function postLoad(LifecycleEventArgs $eventArgs) 
    { 
     $myEntity = $eventArgs->getEntity(); 

     if($myEntity instanceof \myVendor\myFooBarBundle\Entity\myEntity) 
     { 

      $em = $this->reg->getEntityManager('not_default'); 
      $userPointdbManager = $em->getRepository('FullerUserBundle:UserPointdb'); 

      .... 
     } 
    } 
} 

services: 
    postload.listener: 
    class: myVendor\myFooBarBundle\Listener\myEntityListener 
    tags: 
     - { name: doctrine.event_listener, event: postLoad } 
    arguments: 
     - @doctrine 

マイリスナーを。

0

最後の例は、変更後に私のために働き始めました。 Symfony \ Bundle \ DoctrineBundle \ Registryを使用してください。 Doctrine \ Bundle \ DoctrineBundle \ Registry;を使用します。

だから、それは次のようになります。

 
namespace myVendor\myFooBarBundle\Listener\myEntityListener; 

use Doctrine\Bundle\DoctrineBundle\Registry 

class myFooBarEntityListener 
{ 

    private $reg; 

    public function __construct(Registry $reg) 
    { 
     //dont't put your entitymanager otherwise a loop appear during creation 
     $this->reg = $reg; 
    } 

    public function postLoad(LifecycleEventArgs $eventArgs) 
    { 
     $myEntity = $eventArgs->getEntity(); 

     if($myEntity instanceof \myVendor\myFooBarBundle\Entity\myEntity) 
     { 

      $em = $this->reg->getEntityManager('not_default'); 
      $userPointdbManager = $em->getRepository('FullerUserBundle:UserPointdb'); 

      .... 
     } 
    } 
} 
0

パラメータとしてレジストリを設定していませんが、答えをRegistryInterface(symfonyの\橋\教義\ RegistryInterfaceを使用)