diff --git a/UPGRADE.md b/UPGRADE.md index 1db52439499..f9bdc0ad9b8 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -9,16 +9,17 @@ It will be a full-fledged class, no longer extending When the `AUTO` identifier generation strategy was introduced, the best strategy at the time was selected for each database platform. -A lot of time has passed since then, and support for better strategies has been -added. +A lot of time has passed since then, and with ORM 3.0.0 and DBAL 4.0.0, support +for better strategies will be added. Because of that, it is now deprecated to rely on the historical defaults when -they differ from what we recommend now. +they differ from what we will be recommended in the future. Instead, you should pick a strategy for each database platform you use, and it will be used when using `AUTO`. As of now, only PostgreSQL is affected by this. -It is recommended that PostgreSQL user configure their new applications to use -`IDENTITY`: + +It is recommended that PostgreSQL users configure their existing and new +applications to use `SEQUENCE` until `doctrine/dbal` 4.0.0 is released: ```php use Doctrine\DBAL\Platforms\PostgreSQLPlatform; @@ -26,12 +27,12 @@ use Doctrine\ORM\Configuration; assert($configuration instanceof Configuration); $configuration->setIdentityGenerationPreferences([ - PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_IDENTITY, + PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_SEQUENCE, ]); ``` -If migrating an existing application is too costly, the deprecation can be -addressed by configuring `SEQUENCE` as the default strategy. +When DBAL 4 is released, `AUTO` will result in `IDENTITY`, and the above +configuration should be removed to migrate to it. ## Deprecate `EntityManagerInterface::getPartialReference()` diff --git a/docs/en/reference/basic-mapping.rst b/docs/en/reference/basic-mapping.rst index 3bc4b5d33fe..66b552a1d87 100644 --- a/docs/en/reference/basic-mapping.rst +++ b/docs/en/reference/basic-mapping.rst @@ -427,20 +427,6 @@ defaults to the identifier generation mechanism your current database vendor preferred at the time that strategy was introduced: ``AUTO_INCREMENT`` with MySQL, sequences with PostgreSQL and Oracle and so on. -We now recommend using ``IDENTITY`` for PostgreSQL, and you can achieve -that while still using the ``AUTO`` strategy, by configuring what it -defaults to. - -.. code-block:: php - - setIdentityGenerationPreferences([ - PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - ]); .. _identifier-generation-strategies: diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 2ad71382e85..67ff0ef726e 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -34,7 +34,6 @@ use function assert; use function class_exists; -use function constant; use function count; use function end; use function explode; @@ -74,26 +73,10 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory /** @var mixed[] */ private $embeddablesActiveNesting = []; - private const LEGACY_DEFAULTS_FOR_ID_GENERATION = [ - 'Doctrine\DBAL\Platforms\MySqlPlatform' => ClassMetadata::GENERATOR_TYPE_IDENTITY, + private const NON_IDENTITY_DEFAULT_STRATEGY = [ 'Doctrine\DBAL\Platforms\PostgreSqlPlatform' => ClassMetadata::GENERATOR_TYPE_SEQUENCE, - Platforms\DB2Platform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - Platforms\MySQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, Platforms\OraclePlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, Platforms\PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, - Platforms\SQLServerPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - Platforms\SqlitePlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - ]; - - private const RECOMMENDED_STRATEGY = [ - 'Doctrine\DBAL\Platforms\MySqlPlatform' => 'IDENTITY', - 'Doctrine\DBAL\Platforms\PostgreSqlPlatform' => 'IDENTITY', - Platforms\DB2Platform::class => 'IDENTITY', - Platforms\MySQLPlatform::class => 'IDENTITY', - Platforms\OraclePlatform::class => 'SEQUENCE', - Platforms\PostgreSQLPlatform::class => 'IDENTITY', - Platforms\SQLServerPlatform::class => 'IDENTITY', - Platforms\SqlitePlatform::class => 'IDENTITY', ]; /** @return void */ @@ -657,7 +640,7 @@ private function completeIdGeneratorMapping(ClassMetadataInfo $class): void 'https://github.com/doctrine/orm/issues/8850', <<<'DEPRECATION' Context: Loading metadata for class %s -Problem: Using the IDENTITY generator strategy with platform "%s" is deprecated and will not be possible in Doctrine ORM 3.0. +Problem: Using identity columns emulated with a sequence is deprecated and will not be possible in Doctrine ORM 3.0. Solution: Use the SEQUENCE generator strategy instead. DEPRECATION , @@ -762,27 +745,25 @@ private function determineIdGeneratorStrategy(AbstractPlatform $platform): int } } - foreach (self::LEGACY_DEFAULTS_FOR_ID_GENERATION as $platformFamily => $strategy) { + foreach (self::NON_IDENTITY_DEFAULT_STRATEGY as $platformFamily => $strategy) { if (is_a($platform, $platformFamily)) { - $recommendedStrategyName = self::RECOMMENDED_STRATEGY[$platformFamily]; - if ($strategy !== constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $recommendedStrategyName)) { + if ($platform instanceof Platforms\PostgreSQLPlatform || is_a($platform, 'Doctrine\DBAL\Platforms\PostgreSqlPlatform')) { Deprecation::trigger( 'doctrine/orm', 'https://github.com/doctrine/orm/issues/8893', <<<'DEPRECATION' -Relying on non-optimal defaults for ID generation is deprecated. +Relying on non-optimal defaults for ID generation is deprecated, and IDENTITY +results in SERIAL, which is not recommended. Instead, configure identifier generation strategies explicitly through configuration. -We currently recommend "%s" for "%s", so you should use +We currently recommend "SEQUENCE" for "%s", so you should use $configuration->setIdentityGenerationPreferences([ - "%s" => ClassMetadata::GENERATOR_TYPE_%s, + "%s" => ClassMetadata::GENERATOR_TYPE_SEQUENCE, ]); DEPRECATION , - $recommendedStrategyName, - $platformFamily, $platformFamily, - $recommendedStrategyName + $platformFamily ); } diff --git a/psalm-baseline.xml b/psalm-baseline.xml index bcb47d1a2be..95792770be8 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -537,6 +537,7 @@ $class $class $platformFamily + diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php index eae9e871192..bb9256a7768 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php @@ -170,37 +170,37 @@ private function setUpCmfForPlatform(AbstractPlatform $platform, array $preferen return $cmf; } - public function testRelyingOnLegacyIdGenerationDefaultsIsDeprecatedIfItResultsInASuboptimalDefault(): void + public function testRelyingOnLegacyIdGenerationDefaultsIsOKIfItResultsInTheCurrentlyRecommendedStrategyBeingUsed(): void { $cm = $this->createValidClassMetadata(); $cm->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); - - $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform()); + $cmf = $this->setUpCmfForPlatform(new OraclePlatform()); $cmf->setMetadataForClass($cm->name, $cm); - $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); + $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); $cmf->getMetadataFor($cm->name); } - public function testSpecifyingIdGenerationStrategyThroughConfigurationFixesTheDeprecation(): void + public function testRelyingOnLegacyIdGenerationDefaultsIsDeprecatedIfItResultsInADefaultThatWillChange(): void { $cm = $this->createValidClassMetadata(); $cm->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); - $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform(), [ - PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - ]); + $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform()); $cmf->setMetadataForClass($cm->name, $cm); - $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); + $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); $cmf->getMetadataFor($cm->name); } - public function testRelyingOnLegacyIdGenerationDefaultsIsOKIfItResultsInTheCurrentlyRecommendedStrategyBeingUsed(): void + public function testSpecifyingIdGenerationStrategyThroughConfigurationFixesTheDeprecation(): void { $cm = $this->createValidClassMetadata(); $cm->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); - $cmf = $this->setUpCmfForPlatform(new OraclePlatform()); + + $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform(), [ + PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, + ]); $cmf->setMetadataForClass($cm->name, $cm); $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893');