多学说实施

Multiple Doctrine implementation

我正在使用 Symfony4 和 Doctrine,我想用 ODM 和 ORM 制作我的应用程序 "compatible"。

为此,我将我的文档(我的应用程序最初仅是 ODM)更改为 "generic models"(从 App\Model\Documents 移动到 App\Model\Persistence)并尝试使用 XML 映射.

我在 doctrine.yamldoctrine_mongodb.yaml 配置文件中将映射选项更改为 xml

来自像 FosUserBundle 和 this link 这样的例子(这不适用于 symfony4,但我没有找到任何类似的 symfony4 页面),我在我的 Kernel

中做了这个
/**
 * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
 */
protected function build(ContainerBuilder $container): void
{

    $mappingsODM = array(
        realpath(__DIR__.'/Model/Mapping/ODM') => 'App\Model\Persistence',
        realpath(__DIR__.'/Model/Mapping/ODM/Files') => 'App\Model\Persistence\Files',
    );
    $mappingsORM = array(
        realpath(__DIR__.'/Model/Mapping/ORM') => 'App\Model\Persistence',
        realpath(__DIR__.'/Model/Mapping/ORM/Files') => 'App\Model\Persistence\Files',
    );

    if (class_exists('Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass')) {
        $container->addCompilerPass(DoctrineOrmMappingsPass::createXmlMappingDriver($mappingsORM, [], 'app.backend_type_orm'));
    }

    if (class_exists('Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\DoctrineMongoDBMappingsPass')) {
        $container->addCompilerPass(DoctrineMongoDBMappingsPass::createXmlMappingDriver($mappingsODM, [], 'app.backend_type_mongodb'));
    }
    //this CompilerPass is here to add my Repositories (ODM or ORM) in the ServiceContainer depending a param.
    //$container->addCompilerPass(new DoctrineRepositoryCompilerPass());
}

有了这个,我有以下异常消息

No mapping file found named 'Chapter.mongodb.xml' for class 'App\Model\Persistence\Chapter'.

FQCN 很好,我的映射文件在 src/Model/Mapping/ODM 目录中(我现在只设置 ODM)。

如您所见,在 $mappingsODM 中我设置了我的映射文件夹 => 命名空间,但是当我加载我的存储库时,我在 $driver 变量(在 MetadataFactory 中)中有以下转储

"FOS\UserBundle\Model" => XmlDriver {#59 ▼
    #locator: SymfonyFileLocator {#58 ▼
      #paths: array:1 [▼
        0 => "/var/www/html/rapp/vendor/friendsofsymfony/user-bundle/Resources/config/doctrine-mapping"
      ]
      #prefixes: array:1 [▼
        "/var/www/html/rapp/vendor/friendsofsymfony/user-bundle/Resources/config/doctrine-mapping" => "FOS\UserBundle\Model"
      ]
      #fileExtension: ".mongodb.xml"
      -nsSeparator: "."
    }
    #classCache: null
    #globalBasename: null
  }
  "App\Model\Persistence" => XmlDriver {#61 ▼
    #locator: SymfonyFileLocator {#60 ▼
      #paths: array:2 [▼
        0 => "/var/www/html/rapp/src/Model/Mapping/ODM"
        1 => "/var/www/html/rapp/src/Model/Mapping/ODM/Files"
      ]
      #prefixes: array:2 [▼
        "/var/www/html/rapp/src/Model/Mapping/ODM" => "App\Model\Persistence"
        "/var/www/html/rapp/src/Model/Mapping/ODM/Files" => "App\Model\Persistence\Files"
      ]
      #fileExtension: ".mongodb.xml"
      -nsSeparator: "."
    }
    #classCache: null
    #globalBasename: null
  }

我真的看不出 FosUserBundle 部分和我的有什么区别(当然除了文件夹路径,但它们很好)

我经常php bin/console doctrine:mongodb:cache:clear-metadata查看缓存是否有问题但没有任何变化。

这是我的 xml 映射文件之一

<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
                http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd">
    <document name="App\Model\Persistence\Chapter" repository-class="App\Model\ODM\Repository\ChapterRepository">

        .... my fields

    </document>

</doctrine-mongo-mapping>

我错过了什么吗?一些 KernelCompilerPass 我错过了 ?

编辑:

SymfonyFileLocator:findMappingFile() 方法中,这是我的 $this->paths 转储:

array:1 [▼
  0 => "/var/www/html/rapp/src/Model/Persistence"
]

这不是我的映射文件夹,而是我的 ModelClass 文件夹。所以找不到映射文件 *.mongodb.xml

我自己修好了之后感觉很笨...

这是 doctrine.mongodb.yaml 配置中的 dir 选项。它被设置到我的 Class 文件夹,而它应该是映射文件夹。

注释很好,因为映射在 类 内,但 XML 是错误的。

所以我真的不知道在 DoctrineMongoDBMappingsPass::createXmlMappingDriver() 方法中传递映射路径是什么意思(在第一个参数 $arguments 中),但似乎 dir 选项是改为使用。

编辑:我会尽快将此答案标记为已接受。