3

こんにちは、2 つのエンティティを結合したいと考えています。エンティティは異なるデータベースにあります。

データベース構成をセットアップする方法は次のとおりです。

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;
}

doctrine:schema:update コマンドを使用しようとすると、エラーが発生します。

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

エラー:

[Doctrine\Common\Persistence\Mapping\MappingException]
クラス 'My\Bundle1\Entity\Bundle1Entity' はチェーン構成された名前空間 My\Bundle2\Entity\Bundle2Entity で見つかりませんでした

私のセットアップは正しいですか、それとも何か完全に間違っていますか? 2 つのエンティティ マネージャーとそこに接続を定義し、処理する必要があるバンドルを伝えると仮定します。各バンドルに 1 つのデータベースからのエンティティのみがあることを確認します。

ご協力いただきありがとうございます

4

1 に答える 1

7

この質問は古いようですが、答えはありませんでした。この回答が、この質問に出くわした仲間の Google 社員に役立つことを願っています。

エンティティ マネージャー間でエンティティ間に直接的な関係を設定することはできません。ただし、同じエンティティ マネージャーを共有している場合は、バンドル間で関係を設定できます。

同じエンティティ マネージャーを使用する 2 つのエンティティ間の関係 [2.2+]:

この問題に関するSymfonyのドキュメントを見てください

基本的に、Bundle1 でインターフェイスを作成し、それをエンティティに実装します。Bundle2 で、 @ManyToOne アノテーションをエンティティ自体ではなくインターフェイスにリンクします。次に、config で Symfony にインターフェースを解決する方法を伝えます。

バンドル 1:

<?php

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

namespace My\Bundle1\Entity;

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

interface Bundle1EntityInterface {}

class MyBundle1Entity implements Bundle1EntityInterface
{
    // ...
}

バンドル 2:

<?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 オブジェクトのブレンドの例と説明については、ドキュメントを参照してください。

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

明らかに、イベント リスナーを登録し、バンドル 1 のエンティティ マネージャーを引数として渡す必要があります。

于 2013-06-21T00:36:44.743 に答える