2012-11-30 46 views
3

您好想在兩個實體之間進行連接。該實體在不同的數據庫:Symfony2 - Doctrine2:跨數據庫加入列拋出映射 - 異常

這是我如何設置我的數據庫配置:

doctrine: 
    dbal: 
    default_connection: default 
    connections: 
     default: 
      driver: %database_driver% 
      host:  %database_host% 
      port:  %database_port% 
      dbname: %database_name% 
      user:  %database_user% 
      password: %database_password% 
      charset: UTF8 
      mapping_types: 
       enum: string 
     data_warehouse: 
      driver: %database_data_warehouse_driver% 
      host:  %database_data_warehouse_host% 
      port:  %database_data_warehouse_port% 
      dbname: %database_data_warehouse_name% 
      user:  %database_data_warehouse_user% 
      password: %database_data_warehouse_password% 
      charset: UTF8 
      mapping_types: 
       enum: string 

    orm: 
    auto_generate_proxy_classes: %kernel.debug% 

    default_entity_manager: default 

    entity_managers: 
     default: 
      connection: default 
      mappings: 
       MyBundle1: ~ 


     data_warehouse: 
      connection: data_warehouse 
      mappings: 
       MyBundle2: ~ 

這些都是我的實體:

namespace My\Bundle1\Entity; 
use My\Bundle1\Entity\MyBundle2Entity; 
class MyBundle1Entity 
{ 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 
} 


namespace My\Bundle2\Entity; 
class MyBundle2Entity 
{ 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 


    /** 
    * @var MyBundle1Entity 
    * 
    * @ORM\ManyToOne(targetEntity="My\Bundle1\Entity\MyBundle1Entity") 
    * @ORM\JoinColumn(name="my_bundle1_entity_id", nullable=true) 
    */ 
    private $myBundle1Entity; 
} 

當我嘗試使用原則:模式:update命令時,我得到一個錯誤:

php app/console doctrine:schema:create --dump-sql --em=data_warehouse 

錯誤:

[主義\ COMMON \持久性\製圖\ MappingException]
類 '我\ Bundle1 \實體\ Bundle1Entity' 鏈配置的名稱空間沒有找到我的\ bundle2中\實體\ Bundle2Entity

是我的設置正確還是我做了完全錯誤的事情?我假定我定義了兩個實體管理者,並且有連接並告訴他們,他們必須處理哪些綁定。我確保每個包中只有一個數據庫中的實體。

感謝您的幫助

回答

6

它看起來像這個問題是舊的,但從來沒有回答。我希望這個答案能夠幫助Google員工在這個問題上陷入困境。

您不能在實體管理器之間建立實體之間的直接關係。但是,如果它們共享相同的實體管理器,則可以在捆綁包之間建立關係。使用相同的實體管理器[2.2+] 2個實體之間

關係:

看一看在Symfony docs on the issue

從本質上講,在Bundle1,創建一個接口,然後實現它在你的實體。在Bundle2中,將@ManyToOne註釋鏈接到接口,而不是實體本身。然後,在配置中告訴Symfony如何解析接口。

Bundle1:

<?php 

// src/My/Bundle1/Entity/Bundle1Entity.php 

namespace My\Bundle1\Entity; 

use My\Bundle1\Entity\MyBundle2Entity; // <-- NOT NEEDED 

interface Bundle1EntityInterface {} 

class MyBundle1Entity implements Bundle1EntityInterface 
{ 
    // ... 
} 

bundle2中:

<?php 

// src/My/Bundle2/Entity/Bundle2Entity.php 

namespace My\Bundle2\Entity; 
class MyBundle2Entity 
{ 
    // ... 

    /** 
    * @var MyBundle1Entity 
    * 
    * @ORM\ManyToOne(targetEntity="My\Bundle1\Entity\Bundle1EntityInterface") 
    * @ORM\JoinColumn(name="my_bundle1_entity_id", nullable=true) 
    */ 
    private $myBundle1Entity; 
} 

應用配置:使用不同的實體管理

實體

# app/config/config.yml 
doctrine: 
    # .... 
    orm: 
     # .... 
     resolve_target_entities: 
      My\Bundle1\Entity\Bundle1EntityInterface: My\Bundle1\Entity\Bundle1Entity 

關係2之間

由於實體不能直接綁定,因此必須掛鉤postLoad事件才能設置引用,同時手動持久保存該id。有關將MongoDB對象與ORM對象混合的示例和說明,請參閱docs

這裏是一個骨架(getter/setter方法去除),使用2個實體管理器:

實體:

<?php 

// src/My/Bundle1/Entity/Bundle1Entity.php 

namespace My\Bundle1\Entity; 

class MyBundle1Entity 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 
} 


// src/My/Bundle2/Entity/Bundle2Entity.php 

namespace My\Bundle2\Entity; 
class MyBundle2Entity 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var integer 
    * 
    * @ORM\Column(type="integer") 
    */ 
    private $myBundle1EntityId; 

    /** 
    * @var MyBundle1Entity 
    */ 
    private $myBundle1Entity; 

    public function setMyBundle1Entity($entity) 
    { 
     $this->myBundle1EntityId = $entity->getId(); 
     $this->myBundle1Entity = $entity; 
    } 
} 

事件監聽器:

<?php 

use Doctrine\ORM\EntityManager; 
use Doctrine\ORM\Event\LifecycleEventArgs; 

class MyEventSubscriber 
{ 
    public function __construct(EntityManager $bundle1Em) 
    { 
     $this->bundle1Em = $bundle1Em; 
    } 

    public function postLoad(LifecycleEventArgs $eventArgs) 
    { 
     $myBundle2Entity = $eventArgs->getEntity(); 
     $defaultEm = $eventArgs->getEntityManager(); 
     $myBundle2EntityReflProp = $defaultEm->getClassMetadata('Entity\MyBundle2Entity') 
      ->reflClass->getProperty('myBundle1Entity'); 
     $myBundle2EntityReflProp->setAccessible(true); 
     $myBundle2EntityReflProp->setValue(
      $myBundle1Entity, $this->bundle1Em->getReference('Entity\MyBundle1Entity', $myBundle2Entity->getMyBundle1Id()) 
     ); 
    } 
} 

很明顯,你必須註冊事件監聽器和傳遞bundle 1的實體管理器作爲參數。