Background: I am developing a web application with Symfony5 for a customer. The application should be available for several customers. Each customer should get his own file directory (for pdf etc.) and database. The file-directory is not the problem, but I can't get anywhere with the databases.
According to the Symfony docu you can work with different DBs. I configured this in the config/packages/doctrine.yaml.
doctrine:
dbal:
connections:
Client1:
dbname: client1
host: localhost
port: 3306
user: admin
password: secret_pw
driver: pdo_mysql
server-version: 5.7
Client2:
dbname: client2
host: localhost
port: 3306
user: admin
password: secret_pw
driver: pdo_mysql
server-version: 5.7
orm:
auto_generate_proxy_classes: true
entity_managers:
Client1:
connection: Client1
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
Client1:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: Client1
Client2:
connection: Client2
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
Client2:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: Client2
So far it also works, if I create the database from the CLI and execute the migrations.
But if I want to read e.g. a user from the DB for Client2 (is set in $dbClient) with
$userRepo = $this->getDoctrine()
->getRepository(User::class, $dbClient);
$user = $userRepo->findOneByeEmail($this->userEmail);
the DB for Client1 is ALWAYS set in the repo :((.
Did I do something wrong in the config?
Or is there something else that needs to be configured elsewhere?
Thank you very much for your help
Frank
Both entity managers have the same prefix in your mappings. You should try something like
prefix: 'App\Entity\Client1'
//...
prefix: 'App\Entity\Client2'
That's what they do in the doc.
You inject wrong entity manager
$this->getDoctrine()->getManager('Client2')>getRepository(User::class)->findOneByeEmail($this->userEmail);
Related
I have two databases for my application so I put the entities in two separate folders to simplify things.
Entity/
Local/
User.php
Foo.php
Remote/
Bar.php
but I have an error 500 that I don't understand at the time of connection
[2020-09-03 17:10:58] request.CRITICAL:
Uncaught PHP Exception Doctrine\Persistence\Mapping\MappingException: "The class 'App\Entity\Local\User' was not found in the chain configured namespaces " at /www/myapp/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php line 23 {"exception":"[object] (Doctrine\\Persistence\\Mapping\\MappingException(code: 0): The class 'App\\Entity\\Local\\User' was not found in the chain configured namespaces at /www/myapp/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php:23)"} []
Here is my doctrine.yml configuration
doctrine:
dbal:
default_connection: local
connections:
local:
url: '%env(resolve:DATABASE_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
remote:
url: '%env(resolve:DATABASE_URL_MS)%'
charset: 'UTF-8'
wrapper_class: App\Connections\ConnectionRemote
mapping_types:
timestamp: string
xml: string
schema_filter: $sales$
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: local
entity_managers:
local:
connection: local
mappings:
local:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Local'
prefix: 'App\Entity\Local'
alias: local
AnotherBundle: ~
remote:
connection: remote
mappings:
remote:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Remote'
prefix: 'App\Entity\Remote'
alias: remote
Even stranger, if I refresh my page, I am well connected and the error doesn't come back...
Even crazier, it works very well in dev mode
I think there's a bug in Doctrine, it's the fact that it works in dev and not in prod that put me on the track of the solution.
I had dumped the dev and prod conf to compare the two versions and what I noticed was that doctrine.orm.default_entity_manager was set to default even though it is set to custom in package/doctrine.yaml.
so for the value to be really taken into account you must also set doctrine.orm.default_entity_manager in prod/doctrine.yaml
doctrine:
orm:
default_entity_manager: local
I'd like to have 2 entity managers, one for a SQLite database for entities defined in a bundle, and the other for the main application. That way, I can load the data that never changes into one database, and load fixtures, tests, etc. into the application database. I'd expect the following to dump the sql for the bundle entities, but it doesn't:
bin/console doctrine:schema:update --dump-sql --em=geonames
[OK] No Metadata Classes to process.
Similarly, I would expect easyadmin to let me define classes to the bundle entities, but it also fails.
# easy_admin.yaml
entities:
Administrative:
class: Bordeux\Bundle\GeoNameBundle\Entity\Administrative
The configured class
"Bordeux\Bundle\GeoNameBundle\Entity\Administrative" for the path
"easy_admin.entities.Administrative" is no mapped entity.
I expect it has something to do with namespaces, or maybe the is_bundle parameter. I've spent a few hours hacking at this, following along with the tutorials and documentation about multiple entity managers, but I can't find anything that shows how to handle entities that come from a third-party bundle.
# doctrine.yaml
doctrine:
dbal:
default_connection: default
connections:
default:
url: '%env(resolve:DATABASE_URL)%'
geonames:
url: '%env(DATABASE_GEONAMES_URL)%'
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
geonames:
connection: geonames
mappings:
BordeuxGeoNameBundle:
is_bundle: true
type: annotation
dir: 'Entity'
prefix: 'Geonames\Entity'
alias: Geonames
I have not configured multiple entity managers for the latest and greatest Symfony versions so I setup a little test case and came up with this for a configuration:
orm:
default_entity_manager: default
auto_generate_proxy_classes: true
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
geonames:
connection: geonames
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
BordeuxGeoNameBundle:
is_bundle: true
type: annotation
dir: 'Entity'
prefix: 'Bordeux\Bundle\GeoNameBundle\Entity'
alias: GeoNames
I tested it using:
bin/console doctrine:mapping:info --em=geonames
And confirmed the entities were being mapped. I did not install EasyAdmin and test it but I don't see any reason why it would not work.
The main difference was using the entity namespace for the prefix attribute.
And just for my own future reference, I committed the test project to github.
I am currently using Symfony with multiple entity managers. I did this accordingly to their example.
Everything works fine in dev and test environment. The connections are established and I can fetch, insert, etc my data as I want to. But then I came accross the problem that I seem to can't establish any connection to my databases in my prod environment: When I try to login it prints some standard error message like "You can not login because of some system problem". So I checked the logs: nothing. Maybe I need to adjust my verbosity level in prod? I couldn't find a way to get some kind of actual error message. Due to this reason I started comparing the configurations for the different environments. And there is a difference for doctrine on those three environments: test and dev don't use any file to overwrite some settings specified in the default doctrine configuration file. Prod does. And because I changed much stuff in my doctrine configuration file it seemed plausible that problem is burried right there. I deleted the additional doctrine configuration file for prod environment and it worked as expected again.
Here is my standard doctrine configuration file (dontrine.yaml):
parameters:
# Adds a fallback DATABASE_URL if the env var is not set.
# This allows you to run cache:warmup even if your
# environment variables are not available yet.
# You should not need to change this value.
env(DATABASE_URL): ''
doctrine:
dbal:
default_connection: admin
connections:
admin:
driver: 'pdo_mysql'
server_version: '5.7'
url: '%env(DB_ADMIN_URL)%'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
mail:
driver: 'pdo_mysql'
server_version: '5.7'
url: '%env(DB_MAIL_URL)%'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
host:
driver: 'pdo_mysql'
server_version: '5.7'
url: '%env(DB_HOST_URL)%'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
orm:
default_entity_manager: admin
auto_generate_proxy_classes: '%kernel.debug%'
entity_managers:
admin:
connection: admin
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
Admin:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Admin'
prefix: 'App\Entity\Admin'
alias: Admin
mail:
connection: mail
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
Mail:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Mail'
prefix: 'App\Entity\Mail'
alias: Mail
host:
connection: host
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
Host:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Host'
prefix: 'App\Entity\Host'
alias: Host
This is my additional doctrine.yaml for prod environment:
doctrine:
orm:
metadata_cache_driver:
type: service
id: doctrine.system_cache_provider
query_cache_driver:
type: service
id: doctrine.system_cache_provider
result_cache_driver:
type: service
id: doctrine.result_cache_provider
services:
doctrine.result_cache_provider:
class: Symfony\Component\Cache\DoctrineProvider
public: false
arguments:
- '#doctrine.result_cache_pool'
doctrine.system_cache_provider:
class: Symfony\Component\Cache\DoctrineProvider
public: false
arguments:
- '#doctrine.system_cache_pool'
framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
doctrine.system_cache_pool:
adapter: cache.system
The configuration file for prod environment corresponds to the default one. I tried to add all these additional configurations once per entity manager as I did in the default configuration (for my multiple databases). But I didn't work. I don't actually know what this configuration is responsible for but I guess there is a reason why it has been added to default prod environment. I don't just want to delete it.
My questions are now:
How do I extend the additional configuration properly?
What is the sense in this configuration?
Hello I have a strange behavior with Doctrine on Symfony4 (4.0.9), in the console, after the cache was generated by a first run of some command (in a dev environment) the custom types defined in config/packages/doctrine.yml are no longer taken into account.
Why is this happening and how can I fix it ?
Other informations that may be useful: I copied the app code (controllers, entities, etc.) from a Symfony2 application and imported it in a new Symfony 4 app as I'm in the process of making it compatible with Symfony 4. Also, I don't have this behavior on the web version of the app (the custom types are always recognized)
# config/packages/doctrine.yml
doctrine:
dbal:
# configure these for your database server
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
url: '%env(resolve:DATABASE_URL)%'
types:
enumprofilecompletionstep: 'App\DBAL\EnumProfileCompletionStepPossibleValuesType'
enumsection: 'App\DBAL\EnumSectionType'
enumsex: 'App\DBAL\EnumSexType'
enumstatus: 'App\DBAL\EnumStatusType'
phone_number: 'Misd\PhoneNumberBundle\Doctrine\DBAL\Types\PhoneNumberType'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
Thanks for your time,
MrPOC
I use doctrine ORM in a Symfony 2.8 project.
My project contains several Bundles. For one Bundle, which generates Reports I want to use the db server with the slave replication as not to stress the master db server.
How to set this up?
What I tried so far:
In the config.yml
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
slave:
driver: pdo_mysql
host: '%database_host_slave%'
port: '%database_port_slave%'
dbname: '%database_name_slave%'
user: '%database_user_slave%'
password: '%database_password_slave%'
charset: UTF8
Here I created my second db connection with the values stored in my parameters.yml.
I seem to get the orm configuration I tried to setup in the same file not correctly.
Let my first explain what I need:
I have a "ReportingBundle" which runs a console command. The entity manager is only needed to provide the proper authorization to the needed db server. The queries itself are oure SQL and I don't use the entities.
my service.yml for this bundle:
services:
myproject.reporting.service.csv_report_attachment:
class: Myproject\ReportingBundle\Service\DefaultCsvReportAttachmentService
arguments: ['#doctrine.orm.slave_entity_manager', '#logger', '#myproject.reporting.service.php_template_engine', 'reportingHtmlMailTemplate.php']
Now my non functioning orm setup in the config.yml:
ORM configuration
orm:
auto_generate_proxy_classes: '%kernel.debug%'
# naming_strategy: doctrine.orm.naming_strategy.underscore
default_entity_manager: default
entity_managers:
slave:
connection: slave
mappings:
MyprojectReportingBundle: ~
default:
connection: default
auto_mapping : true
metadata_cache_driver: redis
query_cache_driver: redis
result_cache_driver: redis
This results in
[Doctrine\ORM\ORMException]
Unknown Entity namespace alias 'MyprojectReportingBundle'.
I tried to follow the documentation here:
http://symfony.com/doc/current/reference/configuration/doctrine.html#custom-mapping-entities-in-a-bundle
Question:
What is the correct syntax, so that my query is run on the slave server instead of the default server?
I believe you have everything configured correctly. However, you need to make sure the Entity classes are defined in the Bundle namespace. So for example you'd want to have all the entities defined within Myproject\ReportingBundle\Entity in your example.