Symfony 4 Doctrine, creating Entities from database table - php

New to Symfony here
I am following this tutorial about mapping db tables to entities. I created the blog_post and blog_comment tables in my db.
I tried running this php bin/console doctrine:mapping:import --force AppBundle xml which spit out the following error.
Bundle "AppBundle" does not exist or it is not enabled. Maybe you forgot to
add it in the registerBundles() method of your App\Kernel.php file?
My doctrine.yaml is pretty much out of the box.
Doctrine.yaml
doctrine:
dbal:
# configure these for your database server
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
# With Symfony 3.3, remove the `resolve:` prefix
url: '%env(resolve:DATABASE_URL)%'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
App:
is_bundle: true
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
I created the App.php Class under src/Entity/ and added a line under bundles.php but still get an error. The line I added on bundles.php is
App\Entity\App::class=>['all' => true], since that is the defined namespace of my App.php class.
Another error I get is
PHP Fatal error: Uncaught
Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load
class "App" from namespace "App\Entity\App".
Did you forget a "use" statement for another namespace? in
/var/www/html/quick_tour/src/Kernel.php:32

you must use App rather than AppBundle on Symfony 4

Found similar situation to mine in here as well.
Since Symfony 4 Use App instead of Appbundle

Related

Doctrine: MappingException on server, working localy

Im having this weird issue with doctrine: Im working on an old project using Symfony (3.4.49)
I have to create a new table on its database so I also created a new Entity class, called App\Entity\PayrollPayRulesDefault, on src/Entity, with all other entities
On my local environment, it just worked. But when I pushed it to the staging server to test, it just wont:
request.CRITICAL: Uncaught PHP Exception Doctrine\Persistence\Mapping\MappingException: "The class 'App\Entity\PayrollPayRulesDefault' was not found in the chain configured namespaces " at /var/app/current/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php line 23 {"exception":"[object] (Doctrine\\Persistence\\Mapping\\MappingException(code: 0): The class 'App\\Entity\\PayrollPayRulesDefault' was not found in the chain configured namespaces at /var/app/current/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php:23)"} []
Doctrine config is exactly the same for both envirmoments:
# config/packages/doctrine.yaml
doctrine:
dbal:
default_connection: project
connections:
project:
# configure these for your database server
url: '%env(resolve:DATABASE_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
messagequeue:
# configure these for your database server
url: '%env(resolve:MESSAGING_QUEUE_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
orm:
default_entity_manager: project
entity_managers:
project:
connection: project
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
messagequeue:
connection: messagequeue
mappings:
MessageQueue:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/MessageQueue'
prefix: 'App\Entity\MessageQueue'
alias: MessageQueue
The entity class itself seems correct:
namespace App\Entity;
use App\Entity\Component\EntityComponent;
use Doctrine\ORM\Mapping as ORM;
/**
* PayrollPayRulesDefault
*
* #ORM\Table(name="payroll_pay_rules_default", indexes={#ORM\Index(name="ruleSubType", columns={"ruleSubType"})})
* #ORM\Entity
*/
class PayrollPayRulesDefault extends EntityComponent
{
I tried clearing the cache:
php bin/console cache:clear
php bin/console doctrine:cache:clear-metadata
Tried warming it up too:
php bin/console cache:warmup
Also tried just deleting the cache directory too: nothing changes
Im dont have a lot of experience with symfony, but, from what I can tell, the project configuration seems correct. And is the same on my local server, where it works
So I dont know what to try or investigate anymore. Please help, this is driving me crazy
Alright, I was able to fix it myself finally.
php bin/console cache:clear --env=prod
php bin/console doctrine:cache:clear-metadata --env=prod
php bin/console cache:warmup --env=prod --no-debug
php bin/console doctrine:mapping:info --env=prod

How to load doctrine fixtures if we have multiple databases and connections

I used this documentation : https://symfony.com/doc/4.4/doctrine/multiple_entity_managers.html
So now I can create new databases named legacy and Project like this
doctrince.yaml:
doctrine:
dbal:
default_connection: legacy
connections:
legacy:
driver: pdo_mysql
host: "%env(database_host)%"
port: "%env(database_port)%"
dbname: "%env(database_name)%"
user: "%env(database_user)%"
password: "%env(database_password)%"
charset: UTF8
project:
driver: pdo_mysql
host: "%env(database_host_project)%"
port: "%env(database_port_project)%"
dbname: "%env(database_name_project)%"
user: "%env(database_user_project)%"
password: "%env(database_password_project)%"
charset: UTF8
orm:
default_entity_manager: legacy
entity_managers:
legacy:
connection: legacy
mappings:
Legacy:
is_bundle: false
type: annotation
dir: "%kernel.project_dir%/..."
prefix: '...'
alias: Legacy
project:
connection: project
auto_mapping: true
mappings:
Project:
is_bundle: false
type: annotation
dir: "%kernel.project_dir%/src/Entity"
prefix: 'App\Entity'
alias: Project
Now I have several Fixture classes all of them depend on each other and also some will create fixture for legacy and some will create for project.
Now my question is when I do:
php bin/console doctrine:fixtures:load --em=legacy
It runs the appfixtures of the project but not the of the bundle.
and then i get this error:
The class .. was not found in the chain configured namespaces ....
My question is now how can I load fixtures on multiple databases with multiple connections.
Thanks in advance.
You should read this doc : https://symfony.com/doc/current/doctrine/multiple_entity_managers.html
I think it may solve your problem as this is exactly what you trying to do.
If you have to create a fixture for legacy just use :
$entityManager = $this->getDoctrine()->getManager('legacy');`
else if it is for project use
$entityManager = $this->getDoctrine()->getManager('project');`
Also, if you change doctrine.dbal.default_connection, entityManager will run against the defined connection.
So you can try to create group of fixtures.
And then run fixtures for project :
Edit config for test environment
#config/packages/test/doctrine.yaml
doctrine:
dbal:
default_connection: 'project'
Then run fixture for 'project' group
> php bin/console doctrine:fixtures:load --group=project
Then do the same thing for 'legacy'

How to fix migrations running on both databases when setting up multiple databases with symfony4 and doctrine

I am trying to setup a second database for a symfony 4.2 project. Everything seems to working fine up until the point where I run migrations where all migrations execute on the given connection instead of only the migrations for the connection it was created.
Following symfony's own documentation about this, my doctrine.yaml looks like this:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
url: '%env(DATABASE_URL)%'
logging:
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
url: '%env(DATABASE_URL_LOG)%'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: default
entity_managers:
default:
connection: default
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
logging:
connection: logging
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: false
mappings:
Log:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Log'
prefix: 'App\Log'
alias: Log
Now with this configuration I am able to run the migration commands with the --em=log/default parameter like this:
php bin/console doctrine:migrations:diff --em=log
php bin/console doctrine:migrations:migrate --em=log
And you get the expected results: It only creates a new migration for a new entity I created at src/Log when I add --em=log.
this is the new entity:
<?php
namespace App\Log;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity()
*/
class LogItem
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
}
However, the migration is created in the default src/Migrations folder and as a result:
1) this migration is also executed when I run doctrine:migrations:migrate --em=default (creating the table in the default database)
2) the entire default schema is loaded into the log database when I run doctrine:migrations:migrate --em=log
So I think the solution would be to split the migration files between the to entity managers into different directories. But I have been spending hours and can't find the way to do this for symfony4. Also, since the symfony documentation mentions absolutely nothing about this I feel like maybe something is wrong in the way it is setup now.
So can anyone tell me what I am doing wrong here? Or can (and if yes: how) do I split the migration files so it will only execute the migrations created for the given entity manager?
doctrine/doctrine-migrations-bundle doesn't support migrations for multiple entity managers out of the box. There are various workarounds to this problem, including:
Container aware migrations (only feasible on Symfony <4)
Storing migration configuration for each entity manager separately and passing it directly via the --configuration option of the doctrine:migrations:migrate command (only feasible if you don't need to inject services/dependencies into your migrations)
Using avaibooksports/doctrine-migrations-multiple-database-bundle (or rolling your own bundle), which implements support for separate configuration per-entity-manager (in which you can specify a separate directory for each entity's migrations, and inject services via factories as needed).
There's an open GitHub issue (opened in 2012) that describes these approaches in more detail. Also see this answer for a summary.
I think you have a typo in your samples.
In your doctrine.yaml file, the names of your entity managers are "default" and "logging".
But in your command line samples you use the entity manager name "log".
It should work when you change the flag from --em=log to --em=logging.

Configuring DoctrineExtensions-Taggable in Symfony fullstack with config.yml

I am having difficulty configuring the Doctrine Extension Taggable provided here:
https://github.com/FabienPennequin/DoctrineExtensions-Taggable
My project is using Symfony 2 Fullstack and my configuration is using yaml while my doctrine entities are using annotation. I installed DoctrineExtensions using composer. Adding "fpn/doctrine-extensions-taggable": "dev-master" to the require section on composer.json and then running composer update. This installed without issue.
I then become lost at this section: https://github.com/FabienPennequin/DoctrineExtensions-Taggable#setup-doctrine
I understand that the metadata is a Doctrine Entity however as previously mentioned I am using yaml for my symfony configuration as well as entity managers. Here is the excerpt from my config.yml file:
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
orm:
default_entity_manager: main
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
main:
connection: default
mappings:
VendorMainBundle:
prefix: Vendor\MainBundle\Entity
taggable:
connection: default
mappings:
taggable:
type: xml
prefix: DoctrineExtensions\Taggable\Entity
dir: %kernel.root_dir%/../vendor/fpn/doctrine-extensions-taggable/metadata
However, when I run php app/console doctrine:mapping:info --em=taggable I get the error:
[Exception]
You do not have any mapped Doctrine ORM entities according to the current configuration. If you have entities or mapping files you should check your mapping configuration for errors.
Should the above command show the mappings described in the xml files?
Thereby allowing me to update the schema in the database?
I used this documenation as reference for the config.yml file: http://symfony.com/doc/current/reference/configuration/doctrine.html#mapping-configuration
I also added this under the config.yml in order to setup the TagListener. Is this correct?
services:
taggable:
class: DoctrineExtensions\Taggable\TagListener
EDIT [#Grimv01k]:
The TagListener requires an argument passed that is an instance of the TagManager Object. I created another service to handle that as follows and passed it to the TagListener:
tag.manager:
class: DoctrineExtensions\Taggable\TagManager
tags:
- { name: doctrine.event_subscriber, connection: default }
arguments:
entity.manager: #doctrine.orm.entity_manager
taggable:
class: DoctrineExtensions\Taggable\TagListener
arguments:
manager: #tag.manager
The TagManager requires an argument of the entityManager however by doing so results in error:
[Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException]
Circular reference detected for service "doctrine.dbal.default_connection", path: "doctrine.dbal.default_connection".
Across the web it's recommended to resolve this error by passing #service_container and in the constructor of the object pull out the entity_manager, however being a vendor I'd prefer not to modify their code. Is there another way?
Just guess: maybe that happens becuse you haven't got tags applied in service, and Doctrine doesn't use this in your complier pass. Try to do it like this:
services:
taggable:
class: DoctrineExtensions\Taggable\TagListener
tags:
- { name: doctrine.event_subscriber, connection: default }

How do I change symfony 2 doctrine mapper to use my custom directory instead of my Entity Directory under the bundle

I use doctrine in my symfony 2.3 application. I want to use a folder structure like
/MyBundleName/User/User.php
for my Entities.
Question:
Is there anyway that I can explicitly map doctrine ORM directly to use an explicit directory instead of defaulting to the Entity Directory of my Bundle?
I would like to keep all related files in their respective directory such as ProductProvider in
/MyBundleName/Product/ProductProvider.php
Any help would be greatly appreciated.
Just to follow up a bit on #Imanol's correct answer, it is possible to have your entities in multiple directories under one entity manager:
doctrine:
orm:
default_entity_manager: default
auto_generate_proxy_classes: %kernel.debug%
entity_managers:
default:
connection: default
mappings:
test01:
connection: test01
mappings:
product:
type: yml
dir: %kernel.root_dir%/../src/Cerad/Bundle/Test01Bundle/Product
prefix: Cerad\Bundle\Test01Bundle\Product
alias: Product
is_bundle: false
user:
type: yml
dir: %kernel.root_dir%/../src/Cerad/Bundle/Test01Bundle/User
prefix: Cerad\Bundle\Test01Bundle\User
alias: User
is_bundle: false
Don't worry about the is_bundle: false entries. The entities can still live in a bundle. Doctrine does not care. And in case you are wondering, the alias parameter lets you do things like:
$repo = $em->getRepository("Product:Product");
you can tell Doctrine the directory where is your entities
doctrine:
orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: false
mappings:
name:
type: php
dir: %kernel.root_dir%/../src/Company/CartoDBBundle/Tests/CartoDB/Entity
Here you have the full documentation Doctrine configuration
I made a similar question a few days ago, there you can read the full answer Cedar gave me
Similar post
I've spent some time trying to figure out the simplest case. This is how I made it work:
doctrine:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
mappings:
AppBundle:
mapping: true
type: annotation
dir: Model
alias: AppBundle
prefix: 'AppBundle\Model'
is_bundle: true
I simply wanted to store my entities in a directory called 'Model' inside my bundle, instead of the default 'Entity'.

Categories