2

Using Symfony 3.4.2 , I am trying to build a relationship between two entities of two different bundles which uses their own databases located on different servers.

In other words, we have two databases, and then two entities managers :

  • One existing MariaDB database [person] which store one "person" table, used by many other applications.
  • One new MariaDB database [app] dedicated for the application.

Note that I can't change anything on that situation (legacy applications must still running). Althought it is planned "in the future" to replace the [person] database by a REST Api.

Following the Symfony doc (https://symfony.com/doc/3.4/doctrine/multiple_entity_managers.html), this gives the following app/config/config.yml file :

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 }

Since the "person" table is to be used by many other applications, I choosed to create a separate bundle.

In terms of entity, I have then 3 entities :

  1. Acme/AnotherBundle/Entity/Person
  2. AppBundle/Entity/Book
  3. AppBundle/Entity/BookInterest

The first entity was generated without any error.

The AppBundle/Entity/Book and AppBundle/Entity/BookInterest entities were generated via bin\console generate:doctrine:entity without any problem.

Before updating the database schema, I added the relationship in the AppBundle/Entity/BookInterest entity class file (relation to Acme/AnotherBundle/Entity/Person and to AppBundle/Entity/Book), following the Symfony doc (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;

But, when I try to update the schema via bin\console doctrine:schema:update --force --em=default, I have the following error message :

In MappingException.php line 37: The class 'Acme\AnotherBundle\Entity\Person' was not found in the chain configured namespaces AppBundle\Entity

Adding "use Acme\AnotherBundle\Entity\Person;" in the top of \src\AppBundle\Entity\BookInterest.php and clearing the cache via bin\console cache:clear does not solve the problem.

Did I miss something in the app/config/config.yml configuration file, or in the \src\AppBundle\Entity\BookInterest.php entity class file ?

Doctrine2 unable to handle one relationship between two entity managers ?

I also found a (quite old) post on a similar problem (Using Relationships with Multiple Entity Managers), which indicates that Doctrine2 is unable to do that (due to the use of two entity managers).

If this is still the case, what is the best way to handle that situation ?

Is using one simple integer field without relation in the AppBundle/Entity/BookInterest for storing person_id and create manuals validation checks (then manual queries) in the BookInterestController is a good practice ?

Thanks a lot in advance for any tips (and good practice advices) to solve that case ! :-)

Levure
  • 335
  • 1
  • 4
  • 16
  • 1
    Lots of words. I think you are asking if Doctrine can relate two entities across different entity managers? If so, the answer is no. – Cerad Dec 18 '17 at 16:14

0 Answers0