doctrine / DoctrineBundle

Symfony Bundle for Doctrine ORM and DBAL
https://www.doctrine-project.org/projects/doctrine-bundle.html
MIT License
4.69k stars 448 forks source link

Doctrine DBAL 2.5 Breaks Symfony if DB Doesn't Exist #351

Closed mattjanssen closed 7 years ago

mattjanssen commented 9 years ago

After updating to DBAL 2.5, Doctrine introduced Doctrine\DBAL\Connection::detectDatabasePlatform() which is different than 2.4. Now in 2.5, any time a repository is instantiated (not even used) by the DI, we get a PDOException if the DB doesn't already exist.

Imagine trying to run app/console doctrine:database:create and getting a "Database doesn't exist!" error. Repositories as services are very common in most projects, so this is a huge issue.

To illustrate quickly, create a fresh Symfony project, letting composer install the AcmeDemoBundle. Then, while trying to generate an entity, you'll get the PDOException.

composer create-project symfony/framework-standard-edition symfony-standard
cd symfony-standard
app/console doctrine:generate:entity --entity=AcmeDemoBundle:Foo
  [Doctrine\DBAL\Exception\ConnectionException]
  An exception occured in driver: SQLSTATE[HY000] [1049] Unknown database 'testdb'

  [Doctrine\DBAL\Driver\PDOException]
  SQLSTATE[HY000] [1049] Unknown database 'testdb'

  [PDOException]
  SQLSTATE[HY000] [1049] Unknown database 'testdb'
guilhermeblanco commented 9 years ago

This seems because you're relying in the auto-detection of platform to be used. Configure the platform to be used as part of DoctrineBundle and live happy. =)

mattjanssen commented 9 years ago

I'm glad you've found a solution! But I'm struggling to put that into code. Could you help me change the above app/console doctrine:generate:entity --entity=AcmeDemoBundle:Foo command to work with your platform idea?

guilhermeblanco commented 9 years ago

http://symfony.com/doc/current/reference/configuration/doctrine.html

Search for platform_service.

mattjanssen commented 9 years ago

I am surprised that installing a new copy of Symfony and running app/console doctrine:generate:entity gives me an error out of the box. I am especially surprised because doctrine:generate:entity used to work right out of the box. And now it doesn't.

Please remember, I am using all of the Symfony Standard defaults. I have change nothing from the standard, so everything should just work.

Symfony documentation doesn't say you need to create a custom platform_service in order to run the doctrine:generate:entity command. I would expect this command to continue to work like it used to before DBAL 2.5. platform_service was never required until now. This is a breaking change, isn't it?

http://symfony.com/doc/current/bundles/SensioGeneratorBundle/commands/generate_doctrine_entity.html

guilhermeblanco commented 9 years ago

@mattjanssen might be... I'm giving you a hand to address the issue right now. Tomorrow I will discuss with others on how to fix this. =)

deeky666 commented 9 years ago

For know you can simply provide the version of the database server you are connecting to like this:

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

As a workaround until we find a solution.

stof commented 9 years ago

See http://www.doctrine-project.org/jira/browse/DBAL-1057 for the DBAL issue

mattjanssen commented 9 years ago

Thank you @deeky666, @guilhermeblanco and @stof for confirming the issue! I was afraid this would be another "me" issue that no one else was experiencing. Those get very frustrating. Can I close this one then?

stof commented 9 years ago

I will keep it opened for now, until we see whether Doctrine can improve this to avoid guessing too early. I will give more visibility to this issue (and hopefully avoid too many duplicates).

thundo commented 9 years ago

Same for me @mattjanssen. I reverted back to DoctrineBundle 1.2 and DBAL 2.4.3 to avoid the issue.

stof commented 9 years ago

@thundo you can keep using DoctrineBundle 1.3. DoctrineBundle itself is not related to this issue at all.

alanhartless commented 9 years ago

This is a problem for us because we use an installer UI to configure the database. Because of DBAL 2.5, the installer fails out of the box since the database isn't configured yet. In the installer, we give the option to select what driver to use and thus can't use the server_version workaround. Reverting to DBAL 2.4 was the only way fix I saw but that's not going to be an option in the long run.

deeky666 commented 9 years ago

@alanhartless we are still working on a solution. Until then if you cannot provide the server_version option please stick to 2.4 until we fixed the issue.

Taluu commented 9 years ago

2.4 also shows this error... And not 2.3

I haven't tested yet with the server_version hack though.

deeky666 commented 9 years ago

@Taluu this is error is related to DBAL >= 2.5. If you get a similar error it must be something different.

Taluu commented 9 years ago

Well, I can't create the database on 2.4, I have the error "the database doesn't exist". So it looks like the same error.... I can drop it if it exists, but that's all.

✘ talus@zoidberg > ~/dev/web/app >  migrate-symfony > sf doctrine:database:create --force -vv

  [Doctrine\DBAL\Exception\ConnectionException]                                           
  An exception occured in driver: SQLSTATE[HY000] [1049] Unknown database 'app_dev'  

Exception trace:
 () at /home/talus/dev/web/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php:103
 Doctrine\DBAL\Driver\AbstractMySQLDriver->convertException() at /home/talus/dev/web/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:133
 Doctrine\DBAL\DBALException::driverException() at /home/talus/dev/web/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php:47
 Doctrine\DBAL\Driver\PDOMySql\Driver->connect() at /home/talus/dev/web/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:360
 Doctrine\DBAL\Connection->connect() at /home/talus/dev/web/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:429
 Doctrine\DBAL\Connection->getDatabasePlatformVersion() at /home/talus/dev/web/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:389
 Doctrine\DBAL\Connection->detectDatabasePlatform() at /home/talus/dev/web/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:328
 Doctrine\DBAL\Connection->getDatabasePlatform() at /home/talus/dev/web/app/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:81
 Doctrine\ORM\Mapping\ClassMetadataFactory->initialize() at /home/talus/dev/web/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:292
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata() at /home/talus/dev/web/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php:211
 Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor() at /home/talus/dev/web/app/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:265
 Doctrine\ORM\EntityManager->getClassMetadata() at /home/talus/dev/web/app/vendor/doctrine/orm/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php:67
 Doctrine\ORM\Repository\DefaultRepositoryFactory->createRepository() at /home/talus/dev/web/app/vendor/doctrine/orm/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php:50
 Doctrine\ORM\Repository\DefaultRepositoryFactory->getRepository() at /home/talus/dev/web/app/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:665
 Doctrine\ORM\EntityManager->getRepository() at /home/talus/dev/web/app/app/cache/dev/appDevDebugProjectContainer.php:5947
 appDevDebugProjectContainer->getWisembly_Meeting_Security_Meeting_AccessRepositoryService() at /home/talus/dev/web/app/app/bootstrap.php.cache:2097
 Symfony\Component\DependencyInjection\Container->get() at /home/talus/dev/web/app/app/cache/dev/appDevDebugProjectContainer.php:6390
 appDevDebugProjectContainer->getSecurity_Access_DecisionManagerService() at /home/talus/dev/web/app/app/bootstrap.php.cache:2097
 Symfony\Component\DependencyInjection\Container->get() at /home/talus/dev/web/app/app/cache/dev/appDevDebugProjectContainer.php:2980
 appDevDebugProjectContainer->getSecurity_AuthorizationCheckerService() at /home/talus/dev/web/app/app/bootstrap.php.cache:2097
 Symfony\Component\DependencyInjection\Container->get() at /home/talus/dev/web/app/app/cache/dev/appDevDebugProjectContainer.php:2993
 appDevDebugProjectContainer->getSecurity_ContextService() at /home/talus/dev/web/app/app/bootstrap.php.cache:2097
 Symfony\Component\DependencyInjection\Container->get() at /home/talus/dev/web/app/app/cache/dev/appDevDebugProjectContainer.php:6141
 appDevDebugProjectContainer->getWisembly_RatingService() at /home/talus/dev/web/app/app/bootstrap.php.cache:2097
 Symfony\Component\DependencyInjection\Container->get() at /home/talus/dev/web/app/app/cache/dev/appDevDebugProjectContainer.php:4933
 appDevDebugProjectContainer->getWisembly_Api4_QuoteService() at /home/talus/dev/web/app/app/bootstrap.php.cache:2097
 Symfony\Component\DependencyInjection\Container->get() at /home/talus/dev/web/app/app/cache/dev/appDevDebugProjectContainer.php:4814
 appDevDebugProjectContainer->getWisembly_Api4_EventService() at /home/talus/dev/web/app/app/bootstrap.php.cache:2097
 Symfony\Component\DependencyInjection\Container->get() at /home/talus/dev/web/app/app/cache/dev/appDevDebugProjectContainer.php:4920
 appDevDebugProjectContainer->getWisembly_Api4_OrganizationService() at /home/talus/dev/web/app/app/bootstrap.php.cache:2097
 Symfony\Component\DependencyInjection\Container->get() at /home/talus/dev/web/app/app/cache/dev/appDevDebugProjectContainer.php:5303
 appDevDebugProjectContainer->getWisembly_Corebundle_Listener_OrganizationService() at /home/talus/dev/web/app/app/bootstrap.php.cache:2097
 Symfony\Component\DependencyInjection\Container->get() at /home/talus/dev/web/app/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php:188
 Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher->lazyLoad() at /home/talus/dev/web/app/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php:128
 Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher->getListeners() at /home/talus/dev/web/app/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php:215
 Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->preProcess() at /home/talus/dev/web/app/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php:107
 Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch() at /home/talus/dev/web/app/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:878
 Symfony\Component\Console\Application->doRunCommand() at /home/talus/dev/web/app/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:195
 Symfony\Component\Console\Application->doRun() at /home/talus/dev/web/app/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:96
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /home/talus/dev/web/app/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:126
 Symfony\Component\Console\Application->run() at /home/talus/dev/web/app/app/console:22

And the server_version makes it work (even if I only put the major value, such as 5 for 5.5 or 5.6). And also for Doctrine 2.5, so this really looks like the same problem to me

deeky666 commented 9 years ago

@Taluu I can see from your stack trace that you are actually using DBAL 2.5. Therefore it's the same issue, yes.

Taluu commented 9 years ago

Yes, just saw on the orm\'s composer that 2.5 is used with the orm on 2.4 (as I have only the orm specified in my composer). So it is indeed a 2.5 error then. My bad.

SoboLAN commented 9 years ago

Is there any progress on this issue ?

I was really looking forward to DBAL 2.5 due to its support for INSERTs in QueryBuilder, but I can't upgrade unless this problem is fixed.

kingcrunch commented 9 years ago

Hi @SoboLAN

You can add server_version to your config

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                dbname:   Symfony2
                user:         root
                password: null
                host:         localhost
                driver:       pdo_mysql
                server_version: 5.6

or if you use the simplified notation

doctrine:
    dbal:
        dbname:   Symfony2
        user:         root
        password: null
        host:         localhost
        driver:       pdo_mysql
        server_version: 5.6
SoboLAN commented 9 years ago

@KingCrunch Does that mean that it won't be fixed and we should always add server_version from now on ?

kingcrunch commented 9 years ago

@SoboLAN I don't know. I'd guess if somebody comes up with a PR nobody would decline it :smile:

stof commented 9 years ago

@SoboLAN please follow the DBAL issue I linked in https://github.com/doctrine/DoctrineBundle/issues/351#issuecomment-65772073 to see any progress done on the resolution. This is where the discussion should happen given that it is not an issue in the bundle itself.

And btw, note that in case you know the MySQL version used by your server (which should be the case most of the time), configuring it explicitly instead of relying on guessing the version will save you 1 DB call for each connection to your database, so it is a good idea to use the explicit configuration anyway.

dzuelke commented 9 years ago

Does the "old" version work with newer server versions?

Because if it does, then that should maybe the default if nothing is explicitly configured, along with a notice that setting explicitly it may improve performance for newer server versions or whatever.

stof commented 9 years ago

@dzuelke in the case of MySQL, yes (the new version just provides a better way to rename indexes thanks to new MySQL features). In the case of SQLServer, no (there is some breaking changes between the different versions)

kingcrunch commented 9 years ago

It's all and only about renaming tables ?! O_o :confused:

stof commented 9 years ago

@KingCrunch for MySQL, the 5.7 platform is about renaming indexes and updating the list of reserved keywords. But for other platforms, it is about much bigger changes (native JSON field in PostgreSQL 9.2+ for instance)

dzuelke commented 9 years ago

Wouldn't a good first step then to be defaulting to the old version for MySQL, and catching the exception and throwing another one saying that server_version is required for MSSQL or Postgres?

dzuelke commented 9 years ago

That seems like a really low-hanging fruit that would eliminate the problem in 99.975% of cases (because the default config has a MySQL connection in it).

stof commented 9 years ago

Once again, please discuss this in the DBAL issue (I posted the link above in this discussion), because it is something the DBAL team is responsible for solving, not the DoctrineBundle team (and there is already some discussion there)

deeky666 commented 9 years ago

@stof it is not true, that manually declaring the server version saves you 1 DB call. The auto detection feature was intended to avoid that by using the server info from the driver when connected. Drivers that do not provide server info directly and require an extra query, are not supported by the new auto detection feature.

stof commented 9 years ago

oh, I thought some of them were requiring a server roundtrip

weaverryan commented 9 years ago

Does anyone know the status now? I don't see a fix, but I'm not able to repeat the behavior anymore with the original directions. I added doctrine/doctrine2#1294, which I hoped would fix the biggest use-case causing this error, but there hasn't been a new tag with that release yet, so that shouldn't yet be fixing things.

Thanks!

Tobion commented 9 years ago

Closing as the issue is resolved. I'm not getting that error anymore when using the latest versions.

Tobion commented 9 years ago

Oh I cannot close. Someone else has to.

Ocramius commented 9 years ago

Closing as the issue is resolved

Reference or it didn't happen

stof commented 9 years ago

@Ocramius I think it is https://github.com/doctrine/doctrine2/pull/1294 (and https://github.com/doctrine/doctrine2/commit/e05930e71482df06982c332b8820a1ae51bd7f28 for the backport, for which it would be great to tag doctrine/orm 2.4.8)

Ocramius commented 9 years ago

Yup, but I can prepare a release sometime next week only, if time allows it On Apr 17, 2015 15:08, "Christophe Coevoet" notifications@github.com wrote:

@Ocramius https://github.com/Ocramius I think it is doctrine/doctrine2#1294 https://github.com/doctrine/doctrine2/pull/1294 (and doctrine/doctrine2@e05930e https://github.com/doctrine/doctrine2/commit/e05930e71482df06982c332b8820a1ae51bd7f28 for the backport, for which it would be great to tag doctrine/orm 2.4.8)

— Reply to this email directly or view it on GitHub https://github.com/doctrine/DoctrineBundle/issues/351#issuecomment-93982250 .

Tobion commented 9 years ago

@Ocramius reminder to tag please

Ocramius commented 9 years ago

Won't get to it atm.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On 23 April 2015 at 16:27, Tobias Schultze notifications@github.com wrote:

@Ocramius https://github.com/Ocramius reminder to tag please

— Reply to this email directly or view it on GitHub https://github.com/doctrine/DoctrineBundle/issues/351#issuecomment-95624919 .

Tobion commented 9 years ago

Still not possible?

Ocramius commented 9 years ago

I'll see what I can do tomorrow, but I can't guarantee it.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On 2 May 2015 at 01:51, Tobias Schultze notifications@github.com wrote:

Still not possible?

— Reply to this email directly or view it on GitHub https://github.com/doctrine/DoctrineBundle/issues/351#issuecomment-98271857 .

weaverryan commented 9 years ago

Thanks @Ocramius :)

Tobion commented 9 years ago

ping

Tobion commented 9 years ago

ping

Ocramius commented 9 years ago

Not yet happening.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On 27 May 2015 at 12:41, Tobias Schultze notifications@github.com wrote:

ping

— Reply to this email directly or view it on GitHub https://github.com/doctrine/DoctrineBundle/issues/351#issuecomment-105880150 .

weaverryan commented 9 years ago

@Ocramius Anything we can do to help? Or is there a longer-term solution where we can help offload some of this work to someone else?

Ocramius commented 9 years ago

No, I simply need to free myself from paid work :-)

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On 27 May 2015 at 14:37, Ryan Weaver notifications@github.com wrote:

@Ocramius https://github.com/Ocramius Anything we can do to help? Or is there a longer-term solution where we can help offload some of this work to someone else?

— Reply to this email directly or view it on GitHub https://github.com/doctrine/DoctrineBundle/issues/351#issuecomment-105911936 .

Tobion commented 9 years ago

ping

Tobion commented 9 years ago

Ping. This is getting ridiculously embarassing and frustrates alot of people. See symfony/symfony-standard#825