Symfony2 - Doctrine2:跨数据库连接列抛出映射异常

2023-08-18php开发问题
0

本文介绍了Symfony2 - Doctrine2:跨数据库连接列抛出映射异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

您好,想在两个实体之间建立连接.实体位于不同的数据库中:

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

学说:数据库:default_connection: 默认连接:默认:驱动程序:%database_driver%主机:%database_host%端口:%database_port%数据库名称:%database_name%用户:%database_user%密码:%database_password%字符集:UTF8映射类型:枚举:字符串数据仓库:驱动程序:%database_data_warehouse_driver%主机:%database_data_warehouse_host%端口:%database_data_warehouse_port%数据库名称:%database_data_warehouse_name%用户:%database_data_warehouse_user%密码:%database_data_warehouse_password%字符集:UTF8映射类型:枚举:字符串形式:auto_generate_proxy_classes: %kernel.debug%default_entity_manager:默认实体经理:默认:连接:默认映射:MyBundle1:~数据仓库:连接:数据仓库映射:MyBundle2:~

这些是我的实体:

命名空间 MyBundle1Entity;使用 MyBundle1EntityMyBundle2Entity;类 MyBundle1Entity{/*** @var 整数** @ORMColumn(name="id", type="integer", nullable=false)* @ORMId* @ORMGeneratedValue(strategy="IDENTITY")*/私人 $id;}命名空间 MyBundle2Entity;类 MyBundle2Entity{/*** @var 整数** @ORMColumn(name="id", type="integer", nullable=false)* @ORMId* @ORMGeneratedValue(strategy="IDENTITY")*/私人 $id;/*** @var MyBundle1Entity** @ORMManyToOne( targetEntity="MyBundle1EntityMyBundle1Entity")* @ORMJoinColumn(name="my_bundle1_entity_id", nullable=true)*/私人 $myBundle1Entity;}

当我尝试使用 science:schema:update 命令时,出现错误:

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

错误:

[DoctrineCommonPersistenceMappingMappingException]
在链配置的命名空间 MyBundle2EntityBundle2Entity

中找不到类MyBundle1EntityBundle1Entity"

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

感谢您的帮助

解决方案

这个问题看起来很老了,但一直没有人回答.我希望这个答案能帮助遇到这个问题的 Google 同事.

您不能跨实体管理器在实体之间建立直接关系.但是,如果捆绑包共享同一个实体管理器,则您可以在它们之间建立关系.

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

查看有关该问题的 Symfony 文档

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

捆绑包 1:

捆绑 2:

应用配置:

# app/config/config.yml教义:# ....形式:# ....resolve_target_entities:MyBundle1EntityBundle1EntityInterface: MyBundle1EntityBundle1Entity

使用不同实体管理器的 2 个实体之间的关系

因为实体不能直接绑定,你必须钩入 postLoad 事件来设置引用,同时手动持久化 id.请参阅 文档有关将 MongoDB 对象与 ORM 对象混合的示例和说明.

这是一个框架(删除了 getter/setter),使用了 2 个实体管理器:

实体:

myBundle1EntityId = $entity->getId();$this->myBundle1Entity = $entity;}}

事件监听器:

bundle1Em = $bundle1Em;}公共函数 postLoad(LifecycleEventArgs $eventArgs){$myBundle2Entity = $eventArgs->getEntity();$defaultEm = $eventArgs->getEntityManager();$myBundle2EntityReflProp = $defaultEm->getClassMetadata('EntityMyBundle2Entity')->reflClass->getProperty('myBundle1Entity');$myBundle2EntityReflProp->setAccessible(true);$myBundle2EntityReflProp->setValue($myBundle1Entity, $this->bundle1Em->getReference('EntityMyBundle1Entity', $myBundle2Entity->getMyBundle1Id()));}}

显然,您必须注册事件侦听器并将捆绑包 1 的实体管理器作为参数传递.

Hi want to make a join between two entities. The entities are in different databases:

Here is how I set up my database config:

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: ~

And these are my entities:

namespace MyBundle1Entity;
use MyBundle1EntityMyBundle2Entity;
class MyBundle1Entity
{

    /**
     * @var integer
     *
     * @ORMColumn(name="id", type="integer", nullable=false)
     * @ORMId
     * @ORMGeneratedValue(strategy="IDENTITY")
     */
    private $id;
}


namespace MyBundle2Entity;
class MyBundle2Entity
{

    /**
     * @var integer
     *
     * @ORMColumn(name="id", type="integer", nullable=false)
     * @ORMId
     * @ORMGeneratedValue(strategy="IDENTITY")
     */
    private $id;


   /**
     * @var MyBundle1Entity
     *
     * @ORMManyToOne( targetEntity="MyBundle1EntityMyBundle1Entity")
     * @ORMJoinColumn(name="my_bundle1_entity_id",  nullable=true)
     */
    private $myBundle1Entity;
}

When I try to use the doctrine:schema:update command, I get an error:

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

Error:

[DoctrineCommonPersistenceMappingMappingException]
The class 'MyBundle1EntityBundle1Entity' was not found in the chain configured namespaces MyBundle2EntityBundle2Entity

Is my setup correct or am I doeing something completely wrong? I assume that I define two entity managers and there connections and tell them, what bundles they have to handle. I ensure that there are only entities from one database in each bundle.

Thanks for your help

解决方案

It looks like this question is old, but was never answered. I'm hoping this answer helps fellow Googlers stumbling across this question.

You can't set up a direct relationship between entities across entity managers. You can set up relationships across bundles, though, if they share the same entity manager.

Relationships between 2 entities using the same entity manager [2.2+]:

Have a look at the Symfony docs on the issue

Essentially, in Bundle1, create an interface, then implement it on your entity. In Bundle2, link your @ManyToOne annotation to the interface instead of the entity itself. Then, tell Symfony in the config how to resolve the interface.

Bundle1:

<?php

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

namespace MyBundle1Entity;

use MyBundle1EntityMyBundle2Entity; // <-- NOT NEEDED

interface Bundle1EntityInterface {}

class MyBundle1Entity implements Bundle1EntityInterface
{
    // ...
}

Bundle2:

<?php

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

namespace MyBundle2Entity;
class MyBundle2Entity
{
    // ...

    /**
     * @var MyBundle1Entity
     *
     * @ORMManyToOne(targetEntity="MyBundle1EntityBundle1EntityInterface")
     * @ORMJoinColumn(name="my_bundle1_entity_id", nullable=true)
     */
    private $myBundle1Entity;
}

App Config:

# app/config/config.yml
doctrine:
    # ....
    orm:
        # ....
        resolve_target_entities:
            MyBundle1EntityBundle1EntityInterface: MyBundle1EntityBundle1Entity

Relationships between 2 entities using a different entity manager

Because the entities cannot be tied directly, you must hook into the postLoad event to set up the reference, while persisting the id manually. See docs for an example and explanation of blending a MongoDB object with an ORM object.

Here's a skeleton (getters/setters removed), using 2 entity managers:

Entities:

<?php

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

namespace MyBundle1Entity;

class MyBundle1Entity
{
    /**
     * @var integer
     *
     * @ORMColumn(name="id", type="integer", nullable=false)
     * @ORMId
     * @ORMGeneratedValue(strategy="IDENTITY")
     */
    private $id;
}


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

namespace MyBundle2Entity;
class MyBundle2Entity
{
    /**
     * @var integer
     *
     * @ORMColumn(name="id", type="integer", nullable=false)
     * @ORMId
     * @ORMGeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var integer
     *
     * @ORMColumn(type="integer")
     */
    private $myBundle1EntityId;

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

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

Event Listener:

<?php

use DoctrineORMEntityManager;
use DoctrineORMEventLifecycleEventArgs;

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

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

Obviously, you'd have to register the event listener and pass bundle 1's entity manager as an argument.

这篇关于Symfony2 - Doctrine2:跨数据库连接列抛出映射异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

PHP实现DeepL翻译API调用
DeepL的翻译效果还是很强大的,如果我们要用php实现DeepL翻译调用,该怎么办呢?以下是代码示例,希望能够帮到需要的朋友。 在这里需要注意,这个DeepL的账户和api申请比较难,不支持中国大陆申请,需要拥有香港或者海外信用卡才行,没账号的话,目前某宝可以...
2025-08-20 php开发问题
168

PHP通过phpspreadsheet导入Excel日期数据处理方法
PHP通过phpspreadsheet导入Excel日期,导入系统后,全部变为了4开头的几位数字,这是为什么呢?原因很简单,将Excel的时间设置问文本,我们就能看到该日期本来的数值,上图对应的数值为: 要怎么解决呢?进行数据转换就行,这里可以封装方法,或者用第三方的...
2024-10-23 php开发问题
287

mediatemple - 无法使用 codeigniter 发送电子邮件
mediatemple - can#39;t send email using codeigniter(mediatemple - 无法使用 codeigniter 发送电子邮件)...
2024-08-23 php开发问题
11

Laravel Gmail 配置错误
Laravel Gmail Configuration Error(Laravel Gmail 配置错误)...
2024-08-23 php开发问题
16

将 PHPMailer 用于 SMTP 的问题
Problem with using PHPMailer for SMTP(将 PHPMailer 用于 SMTP 的问题)...
2024-08-23 php开发问题
4

关于如何在 GoDaddy 服务器中使用 PHPMailer 设置 SMTP 的问题
Issue on how to setup SMTP using PHPMailer in GoDaddy server(关于如何在 GoDaddy 服务器中使用 PHPMailer 设置 SMTP 的问题)...
2024-08-23 php开发问题
17