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 :
- Acme/AnotherBundle/Entity/Person
- AppBundle/Entity/Book
- 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 ! :-)