学说试图加载元数据两次.类'x'在链配置的名称空间中找不到


Doctrine trying to load metadata twice. The class 'x' was not found in the chain configured namespaces

所以我们尝试在一些正在慢慢迁移到Symfony2的遗留项目中安装Behat。

对于一个测试环境,我们打算在内存中使用sqlite数据库,我们尝试用这个例子重置原则。

但不幸的是,当试图运行测试时,我们得到一个错误:

[学说'常见'持久性映射' ' MappingException]
中定义的"beforeScenario"钩子抛出异常公司' '环境' FeatureContext特性::prepareDbSchema ()

类"Entities'ChanceCreationRate'LevelScorelineRateCalculator"在链配置的名称空间中没有找到公司实体' ModelBundle '

经过一些调试,我们注意到学说加载这个实体的元数据成功,但后来它试图再次加载它,然后我们得到这个错误。

我们有两个实体管理器并在config.yml中手动映射

entity_managers:
  default:
    connection: default
    mappings:
      legacy:
        type: yml
        prefix: Entities
        dir: %kernel.root_dir%/../entities/metadata
        is_bundle: false
      CompanyGameBundle: ~
      CompanyModelBundle: ~ # Temporary until db split
      CompanyShotStatsBundle: ~
      CompanySiteBundle: ~
      CompanyTeamStrengthBundle: ~
      CompanyTrainingBundle: ~
      CompanyUserBundle: ~
      CompanyWatcherBundle: ~
      CompanyWorldBundle: ~
      CompanyWorldCupBundle: ~
  model:
    connection: model
    mappings:
      CompanyModelBundle: ~

我有一种感觉,ModelBundle可能在两者中都有错误,但它必须这样,否则一切都会崩溃。

这个实体的正确命名空间是"Entities",并且属于"legacy"映射。

有什么建议,提示如何解决它?怎么了?

编辑:

所以我发现和理由和感觉有点愚蠢现在…ModelBundle中的一个实体与遗留代码中的几个实体有关系(幸运的是它们没有任何进一步的关系),学说试图在进行模型EM映射时加载它们。这就是我们正在重构的方式:/

所以现在的问题是:我可以在映射而不是目录中为显式文件指定映射吗?或者在我们最终移动所有实体并重构与ModelBundle相关的代码之前,我将无法继续进行?

正如您所发现的,所有相互关联的实体必须在同一个EntityManager中具有映射定义。这是因为一个EntityManager不知道任何其他EntityManager,它们不(也不能)相互通信。一个EntityManager需要知道它所管理的所有实体的映射定义。这是故意的。

所以我建议你按照现在的方式去做。在两个entitymanager中都保留CompanyModelBundle,直到您将所有相关实体完全移出遗留环境。

可能替代

如果你这样做是因为你要迁移到一个新的数据库,并且两个数据库都由相同的服务提供(例如,在包含两个数据库/模式的单个主机上的单个MySQL实例),有一个替代方案:

确保两个数据库都可以被同一个用户访问(这样你就可以使用一个Doctrine Connection)。

映射实体,以便它们指定表所在的数据库。使用注解,这看起来像:

/**
 * @ORM'Entity
 * @ORM'Table(name="some_database.some_table")
 */
class SomeEntity

现在您可以安全地将一个数据库中的一个实体与另一个数据库中的另一个实体相关联。

通过这种方式,您可以(并且必须为此工作)为两个数据库使用单个EntityManager,并每次将一个实体移动到新数据库中。