2

使用 Symfony 3.4.2 ,我正在尝试在两个不同捆绑包的两个实体之间建立关系,这两个捆绑包使用位于不同服务器上的自己的数据库。

换句话说,我们有两个数据库,然后是两个实体管理器

  • 一个现有的 MariaDB 数据库 [person],它存储一个“person”表,供许多其他应用程序使用。
  • 一个专用于该应用程序的新 MariaDB 数据库 [应用程序]。

请注意,在这种情况下我无法更改任何内容(旧版应用程序必须仍在运行)。尽管计划“在未来”用 REST Api 替换 [person] 数据库

遵循 Symfony 文档(https://symfony.com/doc/3.4/doctrine/multiple_entity_managers.html),这给出了以下 app/config/config.yml 文件:

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: services.yml }

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
    locale: en

framework:
    #esi: ~
    #translator: { fallbacks: ['%locale%'] }
    secret: '%secret%'
    router:
        resource: '%kernel.project_dir%/app/config/routing.yml'
        strict_requirements: ~
    form: ~
    csrf_protection: ~
    validation: { enable_annotations: true }
    #serializer: { enable_annotations: true }
    default_locale: '%locale%'
    trusted_hosts: ~
    session:
        # https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
        handler_id: session.handler.native_file
        save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
    fragments: ~
    http_method_override: true
    assets: ~
    php_errors:
        log: true

# Twig Configuration
twig:
    debug: '%kernel.debug%'
    strict_variables: '%kernel.debug%'

# Doctrine Configuration
doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver: pdo_mysql
                host: '%database_host%'
                port: '%database_port%'
                dbname: '%database_name%'
                user: '%database_user%'
                password: '%database_password%'
                # charset: UTF8
                charset: utf8mb4
                default_table_options:
                    charset: utf8mb4
                    collate: utf8mb4_unicode_ci
                # if using pdo_sqlite as your database driver:
                #   1. add the path in parameters.yml
                #     e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
                #   2. Uncomment database_path in parameters.yml.dist
                #   3. Uncomment next line:
                #path: '%database_path%'

            acme_another_db :
                driver: pdo_mysql
                host: '%acme_another_database_host%'
                port: '%acme_another_database_port%'
                dbname: '%acme_another_database_name%'
                user: '%acme_another_database_user%'
                password: '%acme_another_database_password%'
                # charset: UTF8
                charset: utf8mb4
                default_table_options:
                    charset: utf8mb4
                    collate: utf8mb4_unicode_ci
                # if using pdo_sqlite as your database driver:
                #   1. add the path in parameters.yml
                #     e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
                #   2. Uncomment database_path in parameters.yml.dist
                #   3. Uncomment next line:
                #path: '%database_path%'

    orm:
        # Let's disable auto_mapping since we have several entity_managers
        # auto_mapping: true

        default_entity_manager: default
        entity_managers:
            default:
                naming_strategy: doctrine.orm.naming_strategy.underscore
                connection: default
                mappings:
                    AppBundle:  ~

            acme_another_em:
                naming_strategy: doctrine.orm.naming_strategy.underscore
                connection: acme_another_db
                mappings:
                    AcmeAnotherBundle: ~

        auto_generate_proxy_classes: '%kernel.debug%'

# Swiftmailer Configuration
swiftmailer:
    transport: '%mailer_transport%'
    host: '%mailer_host%'
    username: '%mailer_user%'
    password: '%mailer_password%'
    spool: { type: memory }

由于“person”表将被许多其他应用程序使用,我选择创建一个单独的包。

就实体而言,我有 3 个实体:

  1. Acme/AnotherBundle/实体/人
  2. AppBundle/实体/书
  3. AppBundle/实体/BookInterest

第一个实体的生成没有任何错误。

AppBundle/Entity/Book 和 AppBundle/Entity/BookInterest 实体是通过生成的,bin\console generate:doctrine:entity没有任何问题。

在更新数据库模式之前,我按照 Symfony 文档 ( http://symfony. com/doc/3.4/doctrine/associations.html)。

/**
 * @ORM\ManyToOne(targetEntity="Book", inversedBy="book")
 * @ORM\JoinColumn(name="fk_book_id", referencedColumnName="id", nullable=false)
 */
private $book;

/**
 * @ORM\ManyToOne(targetEntity="Acme\AnotherBundle\Entity\Person")
 * @ORM\JoinColumn(name="fk_person_id", nullable=false)
 */
private $person;

但是,当我尝试通过 更新架构时bin\console doctrine:schema:update --force --em=default,出现以下错误消息:

在 MappingException.php 第 37 行:在链配置的命名空间 AppBundle\Entity 中找不到类 'Acme\AnotherBundle\Entity\Person'

添加“使用 Acme\AnotherBundle\Entity\Person;” 在 \src\AppBundle\Entity\BookInterest.php 的顶部并通过清除缓存bin\console cache:clear不能解决问题。

我是否遗漏了app/config/config.yml配置文件或\src\AppBundle\Entity\BookInterest.php实体类文件中的某些内容?

Doctrine2 无法处理两个实体经理之间的一种关系?

我还发现了一篇关于类似问题的(相当旧的)帖子(使用与多个实体管理器的关系),这表明 Doctrine2 无法做到这一点(由于使用了两个实体管理器)。

如果情况仍然如此,处理这种情况的最佳方法是什么?

在 AppBundle/Entity/BookInterest 中使用一个没有关系的简单整数字段来存储 person_id 并在 BookInterestController 中创建手动验证检查(然后是手动查询)是一种好习惯吗?

非常感谢您提供解决该案例的任何提示(和良好的实践建议)!:-)

4

0 回答 0