草庐IT

php - Symfony2 - Doctrine2 : Cross-Database Join Column throws Mapping-Exception

coder 2024-04-29 原文

您好,想在两个实体之间进行连接。实体在不同的数据库中:

这是我设置数据库配置的方式:

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

错误:

[学说\通用\持久性\映射\映射异常]
在链配置的命名空间 My\Bundle2\Entity\Bundle2Entity 中找不到类“My\Bundle1\Entity\Bundle1Entity”

我的设置是正确的还是我做的事情完全错误?我假设我定义了两个实体管理器和连接并告诉他们,他们必须处理哪些包。我确保每个包中只有来自一个数据库的实体。

谢谢你的帮助

最佳答案

看起来这个问题很老了,但是从来没有人回答过。我希望这个答案能帮助遇到这个问题的其他 Google 员工。

您不能跨实体管理器在实体之间建立直接关系。不过,如果它们共享同一个实体管理器,您可以跨捆绑设置关系。

使用同一实体管理器 [2.2+] 的 2 个实体之间的关系:

看看 Symfony docs on the issue

本质上,在 Bundle1 中,创建一个接口(interface),然后在您的实体上实现它。在 Bundle2 中,将您的 @ManyToOne 注释链接到接口(interface)而不是实体本身。然后,在配置中告诉 Symfony 如何解析接口(interface)。

bundle 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
{
    // ...
}

bundle 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 个实体之间的关系

因为无法直接绑定(bind)实体,所以您必须挂接到 postLoad 事件以设置引用,同时手动保留 id。参见 docs有关将 MongoDB 对象与 ORM 对象混合的示例和说明。

这是一个框架(删除了 getters/setters),使用了 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 的实体管理器作为参数传递。

关于php - Symfony2 - Doctrine2 : Cross-Database Join Column throws Mapping-Exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13648974/

有关php - Symfony2 - Doctrine2 : Cross-Database Join Column throws Mapping-Exception的更多相关文章

随机推荐