Doctrinebundle: BC break between 1.6.7 -> 1.6.8 regarding driver selection

Created on 27 Jun 2017  ยท  20Comments  ยท  Source: doctrine/DoctrineBundle

After upgrading from 1.6.7 to 1.6.8, all our tests started failing. While investigating, found that DBAL driver is somehow not picked up correctly.
All functional tests failing with:

Doctrine\DBAL\Exception\DriverException: An exception occured in driver: could not find driver

It suddenly tries to load pdo_mysql instead of pdo_pgsql.

Bisected this breakage to commit 99a62a7c4139c0ccb6969de5eff1447b1a6cbaf4.

This is what our DBAL config looks like:

doctrine:
    dbal:
        default_connection: xxx
        connections:
            xxx:
                server_version: 9.4
                driver: "%database_driver%"
                host: "%database_host%"
                port: "%database_port%"
                dbname: "%database_name%"
                user: "%database_user%"
                password: "%database_password%"
                charset: UTF8
                mapping_types:
                    bit: boolean
                    tsvector: string
        types:
            foo:
                class: X\Y\Types\FooType # <-- commented type
Bug

Most helpful comment

In my case I just specified the server_version and it just worked:

doctrine:
    dbal:
        driver: pdo_mysql
        host: '%database_host%'
        port: '%database_port%'
        dbname: '%database_name%'
        user: '%database_user%'
        password: '%database_password%'
        charset: UTF8
        server_version: '5.7' # Dark magic here

All 20 comments

Indeed, $platform = $connection->getDatabasePlatform(); is the culprit here.

@mikeSimonson how much of an issue would a reversal of the bugfix be? I think this one is more critical...

Does that mean that somehow the $connection->getDatabasePlatform(); call override the server version config value ? Reading the code it seems like it shouldn't be the case (it bails out if it's already set).

@Majkl578 Can you dig further with xdebug to see how that value gets changed ?

@mikeSimonson $connection->getDatabasePlatform() needs to know the server version, to get the right platform. If you have not configured it explicitly in the config, DBAL tries to guess it, and that requires connecting to the server.

However, I don't see any reason for using MySQL (unless your project does weird thing changing the database config at runtime to move it from mysql to postgresql, and the code now connects before your magic.

@Ocramius I'm in favor of reverting the bugfix and deprecating the feature entirely. Marking a type as commented should be done in the Type class itself rather than in the bundle config (DBAL supports marking a type as commented in the Type itself since 2.4)

Hi the problem ist not with @mikeSimonson changes introduced with commit 99a62a7c4139c0ccb6969de5eff1447b1a6cbaf4

Applying the commented types even if no "un"commented types exist is a valid fix.

Analysis

After consulting wit @Ocramius the assumption is, that because now CommentedTypes are always registered, doctrine tries to register them on the predefined default_connection.

bundle

The problem is that we are now registering types on a connection we don't use, or in this case isn't woking at all.

Solution

A solution would be to handle the type registration within DBAL but because of this breaking backwards compatibility the only thing we can do right now is to throw some more descriptive exception so the user understand the problem.

Amazing analysis, thanks @sebastianfeldmann!

Closing this, as the original patch WAS correct.

@Majkl578 the problem is that your "generic connection" service still exists and is used in some services, even though the connection was never established before.

@sebastianfeldmann Good job there. In other words, 99a62a7 just exposed the _issue_ which was just hiding there previously... And now this is marked as an expected BC break in bugfix version...

Anyway, this behavior doesn't make any sense IMHO. I'm explicitly registering only one connection and default_connection points to this specific connection, so why is the bundle even trying to create a connection that was not requested or even used anywhere? (Also _driver_ defaulting to _pdo_mysql_ is just another crazy assumption, but that's different story.) ๐Ÿ˜•

So what should I change to fix this then?

why is the bundle even trying to create a connection that was not requested or even used anywhere?

Usually something referencing the service in a hardcoded way

@Majkl578 Had you finally traced the reason why doctrine.dbal.default_connection is created? I have the same issue here and I almost sure the app does not require doctrine.dbal.default_connection service directly.

@Ocramius Is there any chance doctrine.dbal.default_connection is required somewhere inside of doctrine by some reasons?

a question i try to move symfony to heroku; in local works fine but when i deplay on heroku i found this error ...
what is the solution?

thanks

In ConnectionFactory.php line 96:

         An exception occured while establishing a connection to figure out your pla  
         tform version.                                                               
         You can circumvent this by setting a 'server_version' configuration value    

         For further information have a look at:                                      
         https://github.com/doctrine/DoctrineBundle/issues/673 

maybe the solution is path: 'php://stderr'

I soved doing like this

app\config\config.yml

yml doctrine: dbal: default_connection: prod connections: prod: server_version: 9.4 driver: pdo_mysql host: "%database_host%" port: "%database_port%" dbname: "%database_name%" user: "%database_user%" password: "%database_password%" charset: UTF8 mapping_types: uuid_binary: binary

@lutonda Thanks for your solution ! How did you get the server_version value ?

I'm using debian, just run
mysql -V

In my case I just specified the server_version and it just worked:

doctrine:
    dbal:
        driver: pdo_mysql
        host: '%database_host%'
        port: '%database_port%'
        dbname: '%database_name%'
        user: '%database_user%'
        password: '%database_password%'
        charset: UTF8
        server_version: '5.7' # Dark magic here

I have same problem with symfony 4 + postgrqs 9.6, "server_version" it work for me, in my doctrine.yaml.Thanks.

@aguidis when using your example I encountered the following error:

In DBALException.php line 76:

  Invalid platform version "'5.7'" specified. The platform version has to be   
  specified in the format: "<major_version>.<minor_version>.<patch_version>".  

Changing from this:

server_version: '5.7' # Dark magic here

to this:

server_version: 5.7.0 # Dark magic here

Appears to have fixed my issue.

This is a huge problem for me - I am running into this issue on install and server_version is not allowed in the installer.yml (version ~5.8.0)

Where would you identify the server_version in order to run the installer?

Hello i have the same issue it seems that i need to specify my doctrine dbal server_version, but i can't find where, here is a tree of my project..:

.
โ”œโ”€โ”€ app
โ”‚ โ”œโ”€โ”€ AppCache.php
โ”‚ โ”œโ”€โ”€ AppKernel.php
โ”‚ โ”œโ”€โ”€ AppKernel.php~
โ”‚ โ”œโ”€โ”€ config
โ”‚ โ”‚ โ”œโ”€โ”€ config_dev.yml
โ”‚ โ”‚ โ”œโ”€โ”€ config_dev.yml~
โ”‚ โ”‚ โ”œโ”€โ”€ config_prod.yml
โ”‚ โ”‚ โ”œโ”€โ”€ config.yml
โ”‚ โ”‚ โ”œโ”€โ”€ override
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ config.yml
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ routing.yml
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ Services
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ entities_manager.yml
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ forms.yml
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ services.yml
โ”‚ โ”‚ โ”œโ”€โ”€ parameters.yml
โ”‚ โ”‚ โ”œโ”€โ”€ parameters.yml~
โ”‚ โ”‚ โ”œโ”€โ”€ parameters.yml.dist
โ”‚ โ”‚ โ”œโ”€โ”€ routing.yml
โ”‚ โ”‚ โ”œโ”€โ”€ rsync_exclude.txt
โ”‚ โ”‚ โ”œโ”€โ”€ security.yml
โ”‚ โ”‚ โ””โ”€โ”€ services.yml
โ”‚ โ”œโ”€โ”€ console
โ”‚ โ””โ”€โ”€ Resources
โ”‚ โ””โ”€โ”€ views
โ”‚ โ””โ”€โ”€ base.html.twig
โ”œโ”€โ”€ auth.json
โ”œโ”€โ”€ auth.json.dist
โ”œโ”€โ”€ bin
โ”‚ โ”œโ”€โ”€ behat -> ../vendor/behat/behat/bin/behat
โ”‚ โ”œโ”€โ”€ console
โ”‚ โ”œโ”€โ”€ cssmin -> ../vendor/tubalmartin/cssmin/cssmin
โ”‚ โ”œโ”€โ”€ doctrine -> ../vendor/doctrine/orm/bin/doctrine
โ”‚ โ”œโ”€โ”€ doctrine-dbal -> ../vendor/doctrine/dbal/bin/doctrine-dbal
โ”‚ โ”œโ”€โ”€ doctrine-migrations -> ../vendor/doctrine/migrations/bin/doctrine-migrations
โ”‚ โ”œโ”€โ”€ php-parse -> ../vendor/nikic/php-parser/bin/php-parse
โ”‚ โ”œโ”€โ”€ phpunit -> ../vendor/phpunit/phpunit/phpunit
โ”‚ โ”œโ”€โ”€ security-checker -> ../vendor/sensiolabs/security-checker/security-checker
โ”‚ โ”œโ”€โ”€ selenium-head
โ”‚ โ”œโ”€โ”€ selenium-headless
โ”‚ โ”œโ”€โ”€ simple-phpunit -> ../vendor/symfony/phpunit-bridge/bin/simple-phpunit
โ”‚ โ”œโ”€โ”€ symfony_requirements
โ”‚ โ””โ”€โ”€ update-app
โ”œโ”€โ”€ CODING_STANDARD.md
โ”œโ”€โ”€ composer.json
โ”œโ”€โ”€ composer.lock
โ”œโ”€โ”€ composer.phar
โ”œโ”€โ”€ doc
โ”œโ”€โ”€ features
โ”œโ”€โ”€ LICENSE
โ”œโ”€โ”€ packages.json.dist
โ”œโ”€โ”€ phpmd.xml

This is taking me hours...

well, probably in app/config/config.yml. Look at where you are configuring the other Doctrine settings.

My solution was to just start my database server. -___- Really confusing error message for such a simple problem.

Was this page helpful?
0 / 5 - 0 ratings