Skip to content
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

Unable to execute orm:generate-proxies #6512

Closed
Alvaro948 opened this issue Aug 29, 2024 · 10 comments
Closed

Unable to execute orm:generate-proxies #6512

Alvaro948 opened this issue Aug 29, 2024 · 10 comments

Comments

@Alvaro948
Copy link

Alvaro948 commented Aug 29, 2024

Bug Report

Q A
Version 4.1.0

Summary

Since the update to version 4.1.0 the command for generating proxies fails

Current behaviour

By executing:

./bin/doctrine orm:generate-proxies ./var/doctrine/proxies

Produces:

#41 [prod 18/19] RUN ./bin/doctrine orm:generate-proxies ./var/doctrine/proxies
#41 0.161 PHP Fatal error:  Uncaught TypeError: PDO::__construct(): Argument #2 ($username) must be of type ?string, false given in /www/vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php:33
#41 0.161 Stack trace:
#41 0.161 #0 /www/vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php(33): PDO->__construct()
#41 0.161 #1 /www/vendor/doctrine/dbal/src/Connection.php(217): Doctrine\DBAL\Driver\PDO\PgSQL\Driver->connect()
#41 0.161 #2 /www/vendor/doctrine/dbal/src/Connection.php(236): Doctrine\DBAL\Connection->connect()
#41 0.161 #3 /www/vendor/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php(26): Doctrine\DBAL\Connection->getServerVersion()
#41 0.161 #4 /www/vendor/doctrine/dbal/src/Connection.php(191): Doctrine\DBAL\Driver\AbstractPostgreSQLDriver->getDatabasePlatform()
#41 0.161 #5 /www/vendor/doctrine/orm/src/Mapping/ClassMetadataFactory.php(724): Doctrine\DBAL\Connection->getDatabasePlatform()
#41 0.161 #6 /www/vendor/doctrine/orm/src/Mapping/ClassMetadataFactory.php(546): Doctrine\ORM\Mapping\ClassMetadataFactory->getTargetPlatform()
#41 0.161 #7 /www/vendor/doctrine/orm/src/Mapping/ClassMetadataFactory.php(174): Doctrine\ORM\Mapping\ClassMetadataFactory->completeIdGeneratorMapping()
#41 0.161 #8 /www/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(343): Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata()
#41 0.161 #9 /www/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(207): Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata()
#41 0.161 #10 /www/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(96): Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor()
#41 0.161 #11 /www/vendor/doctrine/orm/src/Tools/Console/Command/GenerateProxiesCommand.php(46): Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata()
#41 0.161 #12 /www/vendor/symfony/console/Command/Command.php(279): Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand->execute()
#41 0.161 #13 /www/vendor/symfony/console/Application.php(1029): Symfony\Component\Console\Command\Command->run()
#41 0.161 #14 /www/vendor/symfony/console/Application.php(316): Symfony\Component\Console\Application->doRunCommand()
#41 0.161 #15 /www/vendor/symfony/console/Application.php(167): Symfony\Component\Console\Application->doRun()
#41 0.161 #16 /www/vendor/doctrine/orm/src/Tools/Console/ConsoleRunner.php(30): Symfony\Component\Console\Application->run()
#41 0.161 #17 /www/bin/doctrine(62): Doctrine\ORM\Tools\Console\ConsoleRunner::run()
#41 0.161 #18 {main}
#41 0.161   thrown in /www/vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php on line 33
#41 ERROR: process "/bin/sh -c ./bin/doctrine orm:generate-proxies ./var/doctrine/proxies" did not complete successfully: exit code: 255

How to reproduce

Execute the provided command with doctrine/[email protected]

Expected behaviour

The same as before, by setting the version back to 4.0.4 the issue is gone:

#41 [prod 18/19] RUN ./bin/doctrine orm:generate-proxies ./var/doctrine/proxies
#41 0.242  Processing entity "App\Domain\Entity\File\FileEntity"
...
#41 0.302 
#41 0.303  Proxy classes generated to "/www/var/doctrine/proxies"
#41 DONE 0.3s
@derrabus
Copy link
Member

Please provide steps to reproduce the issue.

@Alvaro948
Copy link
Author

Alvaro948 commented Aug 30, 2024

Hi @derrabus, sure, I have created a repo in order to reproduce the error https://github.com/Alvaro948/doctrine-starter, on main branch will find doctrine/[email protected], simply install do composer install and if you execute:

./bin/doctrine orm:generate-proxies ./var/doctrine/proxies

It will work, however, if you switch to branch "updated", re-execute composer install (now you have doctrine/[email protected]) the command fails.

@derrabus
Copy link
Member

You're reading the credentials with getenv().

https://github.com/Alvaro948/doctrine-starter/blob/d9efbbd6a0333fe7fc6b30be2ffd7ada28357293/bin/doctrine#L35-L43

If all environment variables are set, the command works fine.

Bildschirmfoto 2024-08-30 um 10 28 14

However, if they're not, getenv() returns false which is not a valid value for the user setting as per our documentation. Either omit the user or set it to null.

We can change the PDO driver and make it throw if the provided user or password are neither a string nor null. This will give you a nicer error message, but in the end it remains a configuration issue on your side.

@derrabus
Copy link
Member

I've created #6513 to make the configuration error more explicit.

@Alvaro948
Copy link
Author

Alvaro948 commented Aug 30, 2024

Hi @derrabus thanks for your answer,

Yes, by setting the env variables it "fixes" the issue, but note that version 4.0.4 did not have this requirement, and most importantly why it this needed in the first place?, I mean, the command is about generating doctrine proxies using the source code, a database connection should not be needed (In my particular use case I execute this command on a CI).

However, I have tried what you suggest without luck, for example, by setting the user & password to null:

$connection = DriverManager::getConnection([
    'driver' => 'pdo_pgsql',
    'user' => null,
    'password' => null,
    'host' => null,
    'port' => null,
    'dbname' => null,
    'charset' => 'UTF8',
], $config);

This, and other combiantions, still fails on version 4.1.0 but works fine on 4.0.4

image

Maybe I have missundertood your answer, as far as I can tell the problem here seems to be that version 4.1.0 is trying to establish a connection with the database even though is not needed, resulting in the type errors your are refeering or in the connection error of the screenshot

@derrabus
Copy link
Member

derrabus commented Aug 30, 2024

why it this needed in the first place?, I mean, the command is about generating doctrine proxies using the source code, a database connection should not be needed (In my particular use case I execute this command on a CI).

This is something we cannot fix it in the DBAL. Long story short: Connections are lazy in DBAL. You can create a connection with invalid parameters and it's fine until you perform any operation that requires an active connection. When loading the class metadata, which the ORM needs to build the proxies, the ORM fetches the database platform object. In order to create that object, we need to know what DBMS we connect to and usually also to which version of that DBMS. So the DBAL establishes a connection in order to detect the server version.

Of course, we could question why fetching the class metadata depends on the database platform, but again: That's an ORM issue and out of scope for this repository.

note that version 4.0.4 did not have this requirement

Yeah, funny story. Well, in DBAL 4.0, we dropped support for Postgres versions before 10. Because of that, we were in the unique situation that we only had a single platform class for all Postgres versions. Since the server version was irrelevant, we could pick the platform class soley based on the driver, so no connection was established.

In 4.1, a new platform class for Postgres 12 and above was added, so we again need to know the server version when detecting the platform.

However, there is a way to short-circuit the platform detection. If you add 'serverVersion' => '16.4', to your config array, the error is gone. Of course, you should replace 16.4 with the actual version of your postgres server.

@derrabus
Copy link
Member

See doctrine/DoctrineBundle#351 for a similar discussion.

@derrabus
Copy link
Member

I'm closing the issue now because there's nothing we can do in DBAL to solve it.

@derrabus derrabus closed this as not planned Won't fix, can't repro, duplicate, stale Aug 30, 2024
@Alvaro948
Copy link
Author

Hi @derrabus,

Yes, I have tried by simply adding serverVersion and it indeed worked (good enought for me):

$connection = DriverManager::getConnection([
    'driver' => 'pdo_pgsql',
    'user' => getenv('DATABASE_USERNAME'),
    'password' => getenv('DATABASE_PASSWORD'),
    'host' => getenv('DATABASE_HOST'),
    'port' => getenv('DATABASE_PORT'),
    'dbname' => getenv('DATABASE_DATABASE'),
    'charset' => 'UTF8',
+   'serverVersion' => '16.4',
], $config);

Also, by simply setting other driver than pdo_pgsql to pdo_sqlite it fixes the issue as well, and all the generated files seem to be exactly the same, but maybe in the future it will change.

Again, thank you so much for your help!

derrabus added a commit that referenced this issue Sep 2, 2024
|      Q       |   A
|------------- | -----------
| Type         | bug
| Fixed issues | #6512 

#### Summary

If `false` (or anything that is not a string) is passed as `user` or
`password`, we run into a `TypeError` because we pass that value as-is
to the constructor of PDO. This started to happen after we enabled
strict types on our driver classes in 4.0.

On 3.9, `false` would implicitly be cast to an empty string which is
either desired or leads to more obscure connection errors. We could
restore the behavior of 3.9 by adding explicit type casts to the two
parameters. But since we don't document `false` as a valid value for
either parameter, my preference would indeed be raising an exception.
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 30, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants