gpt4 book ai didi

php - 交响乐 2.8 : Doctrine getManagerForClass() not returning the right Entity Manager

转载 作者:行者123 更新时间:2023-12-05 04:12:19 24 4
gpt4 key购买 nike

tl;dr getManagerForClass() 方法如何找出适合特定类的实体管理器?

我制作了一个通用 Controller ,它应该能够处理不同实体的基本操作。我还连接到两个不同的数据库,所以我使用了两个实体管理器。

在我的 Controller 中,我正在尝试使用 Doctrine 的 getManagerForClass() 方法来查找每个类要使用的管理器,如 on this blog 所解释的那样和 this SO answer .

但该方法似乎没有区分我的两个实体管理器,只是返回配置中的第一个。

我的 Controller Action 是这样开始的:

public function indexAction($namespace, $entityName)
{
$classFullName = "AppBundle:$namespace\\$entityName";
$em = $this->getDoctrine()->getManagerForClass($classFullName);

这是我的 Doctrine 配置:

dbal:
default_connection: postgres
connections:
postgres:
driver: pdo_pgsql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8

oracle:
driver: oci8
host: "%oracle_host%"
port: "%oracle_port%"
dbname: "%oracle_name%"
user: "%oracle_user%"
password: "%oracle_password%"
charset: UTF8

orm:
auto_generate_proxy_classes: true
entity_managers:
postgres:
connection: postgres
mappings:
AppBundle:
type: annotation
dir: Entity\Postgres
oracle:
connection: oracle
mappings:
AppBundle:
type: annotation
dir: Entity\Oracle

我的文件夹结构如下:

AppBundle
|___Controller
| |___EntityController.php
|
|___Entity
|___Postgres
| |___SomePostgresBasedEntity.php
|
|___Oracle
|___SomeOracleBasedEntity.php

现在我不知道这个方法是如何工作的,如果不通过配置它应该如何知道映射。但是如果我这样调用它,例如:

 $em = $this->getDoctrine()->getManagerForClass("AppBundle:Oracle\\SomeOracleBasedEntity");

...我得到了 Postgres 的实体管理器。

但是,如果我简单地切换实体管理器配置,将 oracle 的配置放在第一位,则之前的调用有效,但以下调用无效:

 $em = $this->getDoctrine()->getManagerForClass("AppBundle:Postgres\\SomePostgresBasedEntity");

更新1

getManagerForClass() 遍历每个管理器并针对每个管理器检查类是否“非 transient ”:

    foreach ($this->managers as $id) {
$manager = $this->getService($id);

if (!$manager->getMetadataFactory()->isTransient($class)) {
return $manager;
}
}

这一直到 AnnotationDriver->isTransient()。文档在这里说了以下内容:

A class is non-transient if it is annotated with an annotation from the AnnotationDriver::entityAnnotationClasses.

@Entity 似乎是使类非 transient 的注释之一。但是,我的任何实体怎么可能是短暂的呢?驱动程序如何仅根据其注释来区分属于特定管理器的实体?我一定是在高年级类(class)中漏掉了什么。

更新2

该方法在使用 yml 映射时有效。

我有点预料到这种行为。不同之处在于不同驱动程序中 isTransient() 方法的实现。如果元数据文件存在于映射配置的 dir: 目录中,则 isTransient 的 FileDriver 实现返回 true

我原以为 AnnotationDriver 只在指定的 dir: 目录中包含的实体中搜索注释,但它似乎忽略了该参数。还是我应该使用另一个?

最佳答案

终于,我解决了它。解决方案是使用 prefix 参数。

entity_managers:
postgres:
connection: postgres
mappings:
AppBundle:
type: annotation
dir: Entity\Postgres
prefix: AppBundle\Entity\Postgres
alias: Postgres
oracle:
connection: oracle
mappings:
AppBundle:
type: annotation
dir: Entity\Oracle
prefix: AppBundle\Entity\Oracle
alias: Oracle

说明

prefix 参数被传递给相应的 Entity Manager 服务,并被添加到 entityNamespaces 属性中,否则默认为 AppBundle/Entity。Annotation Driver 然后将检查特定命名空间 中的注释,而File Driver 检查通过dir 参数指定的目录中的现有映射文件。(alias 参数不是强制性的。)

至少,我是这么理解的。

关于php - 交响乐 2.8 : Doctrine getManagerForClass() not returning the right Entity Manager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40867556/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com