-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Symfony console breaks when injecting an EntityRepository to a service Command and the database is not created #17727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It looks like your issue might be related to: doctrine/DoctrineBundle#351 Setting the server version in your config should fix that: doctrine:
dbal:
default_connection: default
connections:
default:
dbname: Symfony2
user: root
password: null
host: localhost
driver: pdo_mysql
server_version: 5.6 # your database server version here |
Which version of Doctrine/DoctrineBundle are you using? |
@peterrehm 1.6.1 |
BTW I can confirm that this issue is related to the one you linked. Using the Thank you. |
Closing here as there is nothing we can do in Symfony (as the issue is located in Doctrine). |
@xabbuh @Tobion @weaverryan I thought that was fixed already? Is there anything we could do in this regards as it seems quite some people stumble upon this issue... |
Not sure what we can do about this as doctrine/dbal#990 is still open. |
@peterrehm what we need (and what we don't have that I'm aware of) is very repeatable steps when someone hits this. It's very finnicky and only seems to happen under certain conditions. If we can repeat it consistently, then we may be able to fix it on a case-by-case basis. For example, I fixed one situation where Doctrine was loading some metadata (that now requires a DB connection due to the linked issue) but it didn't actually need that metadata in order to accomplish what it was doing. Since then, I've had almost no luck hitting the issue. |
Okay, looks like in the standard edition I am not able to reproduce it with the database:drop command. But it looks like in the code above that it happens once you use console commands as a service and inject the entity manager in the command. With the above mentioned repo it easy to reproduce, see the steps above. One simple fix could be adding the server_version as parameter to the standard edition with 5.6 as default. No matter how we fix it we should provide some solution to avoid people experiencing that road block. |
@weaverryan here is a more concise step by step guide to reproduce this issue:
Now every time you run the console, all the command dependencies will be instantiated, and in the case of the repository a connection to the database will be attempted in order to guess the server version, even though the database doesn't exist. Hardcoding the |
Injecting a PDO-based session handler into a console command also causes this issue, for similar reasons I believe. It can be solved in Symfony 3.4+ by making the command lazy.
|
I've created a "PoC" project in order to ease with the bug reproduction, you can find it here: https://github.com/1ma/symfony-cmd-issue
Project contents
A brand new Symfony3 project with an empty entity (Test), its companion repository (TestRepository) and a command (TestCommand) defined as a service, as per the cookbook entry found at http://symfony.com/doc/current/cookbook/console/commands_as_services.html
Steps to reproduce
$ git clone https://github.com/1ma/symfony-cmd-issue.git
$ cd symfony-cmd-issue; composer install
When the prompt shows up, be sure to set valid values for
database_user
anddatabase_password
. They should map to a MySQL user with enough permissions to create the database.At this point the installation will break. Further calls to
bin/console
will also fail with the following error message:In order to restore the console, remove the
tags:
block from the command service definition. Now you'll be able to execute the console and create the database:Once the database is created you can restore the
tags:
block in the command service definition and the console will still work:Drop the database, and the console breaks again:
Troubleshooting
From what I've seen from the above exception stack trace, it seems that every service tagged with the
console.command
tag is instantiated atApplication::registerCommands()
.Then, if one of the command dependencies is a subclass of
EntityRepository
instantiated asEntityManager->getRepository('AppBundle:EntityName')
a connection to the database will be always attempted down the line, even if it doesn't exist yet.Here is the full stack trace with some of the most relevant entries highlighted in bold font:
#0 .../symfony-cmd-issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php(45): Doctrine\DBAL\Driver\PDOConnection::__construct('mysql:host=127....', 'root', 'root', Array)
#1 .../symfony-cmd-issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(360): Doctrine\DBAL\Driver\PDOMySql\Driver->connect(Array, 'root', 'root', Array)
#2 .../symfony-cmd-issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(429): Doctrine\DBAL\Connection->connect()
#3 .../symfony-cmd-issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(389): Doctrine\DBAL\Connection->getDatabasePlatformVersion()
#4 .../symfony-cmd-issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(328): Doctrine\DBAL\Connection->detectDatabasePlatform()
#5 .../symfony-cmd-issue/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(763): Doctrine\DBAL\Connection->getDatabasePlatform()
#6 .../symfony-cmd-issue/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(616): Doctrine\ORM\Mapping\ClassMetadataFactory->getTargetPlatform()
#7 .../symfony-cmd-issue/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(174): Doctrine\ORM\Mapping\ClassMetadataFactory->completeIdGeneratorMapping(Object(Doctrine\ORM\Mapping\ClassMetadata))
#8 .../symfony-cmd-issue/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(332): Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata(Object(Doctrine\ORM\Mapping\ClassMetadata), NULL, false, Array)
#9 .../symfony-cmd-issue/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(78): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata('AppBundle\Entit...')
#10 .../symfony-cmd-issue/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(216): Doctrine\ORM\Mapping\ClassMetadataFactory->loadMetadata('AppBundle\Entit...')
#11 .../symfony-cmd-issue/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php(281): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor('AppBundle:Test')
#12 .../symfony-cmd-issue/vendor/doctrine/orm/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php(44): Doctrine\ORM\EntityManager->getClassMetadata('AppBundle:Test')
#13 .../symfony-cmd-issue/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php(698): Doctrine\ORM\Repository\DefaultRepositoryFactory->getRepository(Object(Doctrine\ORM\EntityManager), 'AppBundle:Test')
#14 .../symfony-cmd-issue/var/cache/dev/appDevDebugProjectContainer.php(2465): Doctrine\ORM\EntityManager->getRepository('AppBundle:Test')
#15 .../symfony-cmd-issue/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php(273): appDevDebugProjectContainer->getTestRepoService()
#16 .../symfony-cmd-issue/var/cache/dev/appDevDebugProjectContainer.php(2452): Symfony\Component\DependencyInjection\Container->get('test_repo')
#17 .../symfony-cmd-issue/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php(273): appDevDebugProjectContainer->getTestCommandService()
#18 .../symfony-cmd-issue/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(101): Symfony\Component\DependencyInjection\Container->get('test_command')
#19 .../symfony-cmd-issue/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(71): Symfony\Bundle\FrameworkBundle\Console\Application->registerCommands()
#20 .../symfony-cmd-issue/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(117): Symfony\Bundle\FrameworkBundle\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#21 .../symfony-cmd-issue/bin/console(29): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput))
#22 {main}
Further details
Tested on a Debian Jessie x64 virtual machine with PHP 5.6, Symfony 3.0.2 and Doctrine ORM 2.5.4
The text was updated successfully, but these errors were encountered: