From 3c3cc0fed738c333f1aec500a36f481f3b8b4c51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Sat, 1 Feb 2020 18:26:25 +0100 Subject: [PATCH 1/8] Document UOW reset introduced since 1.12.3/2.0.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Grégoire Paris --- UPGRADE-1.12.md | 28 ++++++++++++++++++++++++++++ UPGRADE-2.0.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/UPGRADE-1.12.md b/UPGRADE-1.12.md index c18099699..f50f794db 100644 --- a/UPGRADE-1.12.md +++ b/UPGRADE-1.12.md @@ -15,3 +15,31 @@ Service aliases * Deprecated the `Symfony\Bridge\Doctrine\RegistryInterface` and `Doctrine\Bundle\DoctrineBundle\Registry` service alias, use `Doctrine\Common\Persistence\ManagerRegistry` instead. * Deprecated the `Doctrine\Common\Persistence\ObjectManager` service alias, use `Doctrine\ORM\EntityManagerInterface` instead. + +UnitOfWork cleared between each request +--------------------------------------- +If all of these are true: +* You call `Symfony\Bundle\FrameworkBundle\Client::disableReboot()` in your test case +* Trigger multiple HTTP requests (via `Symfony\Bundle\FrameworkBundle\Client::request()` etc.) within your test case +* Your test case relies on Doctrine ORM keeping references to old entities between requests (this is most obvious when calling `Doctrine\Persistence\ObjectManager::refresh`) + +Your test case will fail since `DoctrineBundle` 1.12.3, as identity map is now cleared between each request +to better simulate real requests and avoid memory leaks. You have two options to solve this: + +1. Change your test cases with new behaviour in mind. In a lot of cases this just means to replace `ObjectManager::refresh($entity)` with `$entity = ObjectManager::find($entity->getId())`. This is the recommended solution. +2. Write a compiler pass which restores old behaviour, e.g. by adding the following to your `Kernel` class: +```php +protected function build(\Symfony\Component\DependencyInjection\ContainerBuilder $container) +{ + parent::build($container); + + if ($this->environment === 'test') { + $container->addCompilerPass(new class implements \Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface { + public function process(\Symfony\Component\DependencyInjection\ContainerBuilder $container) + { + $container->getDefinition('doctrine')->clearTag('kernel.reset'); + } + }, \Symfony\Component\DependencyInjection\Compiler\PassConfig::TYPE_BEFORE_OPTIMIZATION, 1); + } +} +``` diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md index 6567b1424..d554f18c4 100644 --- a/UPGRADE-2.0.md +++ b/UPGRADE-2.0.md @@ -41,3 +41,31 @@ Types the type. * The `commented` configuration option for types will be dropped in a future release. You should not use it. + +UnitOfWork cleared between each request +--------------------------------------- +If all of these are true: +* You call `Symfony\Bundle\FrameworkBundle\Client::disableReboot()` in your test case +* Trigger multiple HTTP requests (via `Symfony\Bundle\FrameworkBundle\Client::request()` etc.) within your test case +* Your test case relies on Doctrine ORM keeping references to old entities between requests (this is most obvious when calling `Doctrine\Persistence\ObjectManager::refresh`) + +Your test case will fail since `DoctrineBundle` 2.0.3, as identity map is now cleared between each request +to better simulate real requests and avoid memory leaks. You have two options to solve this: + +1. Change your test cases with new behaviour in mind. In a lot of cases this just means to replace `ObjectManager::refresh($entity)` with `$entity = ObjectManager::find($entity->getId())`. This is the recommended solution. +2. Write a compiler pass which restores old behaviour, e.g. by adding the following to your `Kernel` class: +```php +protected function build(\Symfony\Component\DependencyInjection\ContainerBuilder $container) +{ + parent::build($container); + + if ($this->environment === 'test') { + $container->addCompilerPass(new class implements \Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface { + public function process(\Symfony\Component\DependencyInjection\ContainerBuilder $container) + { + $container->getDefinition('doctrine')->clearTag('kernel.reset'); + } + }, \Symfony\Component\DependencyInjection\Compiler\PassConfig::TYPE_BEFORE_OPTIMIZATION, 1); + } +} +``` From 6448be3ab9b49022c0237092c256775d8d6dd902 Mon Sep 17 00:00:00 2001 From: rosier Date: Wed, 26 Feb 2020 19:16:06 +0100 Subject: [PATCH 2/8] Update namespace --- Resources/config/orm.xml | 2 +- Tests/DependencyInjection/DoctrineExtensionTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml index e99be0253..4f11579cf 100644 --- a/Resources/config/orm.xml +++ b/Resources/config/orm.xml @@ -29,7 +29,7 @@ Doctrine\Common\Cache\ZendDataCache - Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain + Doctrine\Persistence\Mapping\Driver\MappingDriverChain Doctrine\ORM\Mapping\Driver\AnnotationDriver Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver diff --git a/Tests/DependencyInjection/DoctrineExtensionTest.php b/Tests/DependencyInjection/DoctrineExtensionTest.php index 33554408d..eb1e426ec 100644 --- a/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -262,7 +262,7 @@ public function testDependencyInjectionConfigurationDefaults() $this->assertEquals('11211', $container->getParameter('doctrine.orm.cache.memcache_port')); $this->assertEquals('Memcache', $container->getParameter('doctrine.orm.cache.memcache_instance.class')); $this->assertEquals('Doctrine\Common\Cache\XcacheCache', $container->getParameter('doctrine.orm.cache.xcache.class')); - $this->assertEquals('Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain', $container->getParameter('doctrine.orm.metadata.driver_chain.class')); + $this->assertEquals('Doctrine\Persistence\Mapping\Driver\MappingDriverChain', $container->getParameter('doctrine.orm.metadata.driver_chain.class')); $this->assertEquals('Doctrine\ORM\Mapping\Driver\AnnotationDriver', $container->getParameter('doctrine.orm.metadata.annotation.class')); $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver', $container->getParameter('doctrine.orm.metadata.xml.class')); $this->assertEquals('Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver', $container->getParameter('doctrine.orm.metadata.yml.class')); From acd3d636a3f403879bd479c82cec2b36eea8d1ea Mon Sep 17 00:00:00 2001 From: azzra Date: Tue, 17 Mar 2020 19:01:12 +0100 Subject: [PATCH 3/8] Fix render controller when explaining a query --- Resources/views/Collector/db.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/views/Collector/db.html.twig b/Resources/views/Collector/db.html.twig index 9dc79f6b5..716452e0e 100644 --- a/Resources/views/Collector/db.html.twig +++ b/Resources/views/Collector/db.html.twig @@ -112,7 +112,7 @@ {% set profiler_markup_version = profiler_markup_version|default(1) %} {% if 'explain' == page %} - {{ render(controller('DoctrineBundle:Profiler:explain', { + {{ render(controller('Doctrine\\Bundle\\DoctrineBundle\\Controller\\ProfilerController::explainAction', { token: token, panel: 'db', connectionName: request.query.get('connection'), From 89535170a0ac4a0ebe8f8f0b950e5d47218bcb36 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Tue, 17 Mar 2020 20:16:50 +0100 Subject: [PATCH 4/8] Update deprecation messages to follow the Symfony convention When the class name is enclosed in double quotes, it gets turned into bold when being displayed in the webprofiler. --- DependencyInjection/DoctrineExtension.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DependencyInjection/DoctrineExtension.php b/DependencyInjection/DoctrineExtension.php index 485aaba47..c38639dee 100644 --- a/DependencyInjection/DoctrineExtension.php +++ b/DependencyInjection/DoctrineExtension.php @@ -93,9 +93,9 @@ protected function dbalLoad(array $config, ContainerBuilder $container) $loader->load('dbal.xml'); if (method_exists(Alias::class, 'setDeprecated')) { - $container->getAlias('Symfony\Bridge\Doctrine\RegistryInterface')->setDeprecated(true, 'The "%alias_id%" service alias is deprecated, use `Doctrine\Persistence\ManagerRegistry` instead.'); - $container->getAlias('Doctrine\Bundle\DoctrineBundle\Registry')->setDeprecated(true, 'The "%alias_id%" service alias is deprecated, use `Doctrine\Persistence\ManagerRegistry` instead.'); - $container->getAlias('Doctrine\Common\Persistence\ManagerRegistry')->setDeprecated(true, 'The "%alias_id%" service alias is deprecated, use `Doctrine\Persistence\ManagerRegistry` instead.'); + $container->getAlias('Symfony\Bridge\Doctrine\RegistryInterface')->setDeprecated(true, 'The "%alias_id%" service alias is deprecated, use "Doctrine\Persistence\ManagerRegistry" instead.'); + $container->getAlias('Doctrine\Bundle\DoctrineBundle\Registry')->setDeprecated(true, 'The "%alias_id%" service alias is deprecated, use "Doctrine\Persistence\ManagerRegistry" instead.'); + $container->getAlias('Doctrine\Common\Persistence\ManagerRegistry')->setDeprecated(true, 'The "%alias_id%" service alias is deprecated, use "Doctrine\Persistence\ManagerRegistry" instead.'); } if (empty($config['default_connection'])) { @@ -355,7 +355,7 @@ protected function ormLoad(array $config, ContainerBuilder $container) $loader->load('orm.xml'); if (method_exists(Alias::class, 'setDeprecated')) { - $container->getAlias('Doctrine\Common\Persistence\ObjectManager')->setDeprecated(true, 'The "%alias_id%" service alias is deprecated, use `Doctrine\ORM\EntityManagerInterface` instead.'); + $container->getAlias('Doctrine\Common\Persistence\ObjectManager')->setDeprecated(true, 'The "%alias_id%" service alias is deprecated, use "Doctrine\ORM\EntityManagerInterface" instead.'); } if (class_exists(AbstractType::class)) { From ffc912f286ba91d5a44770b5e28dbf42d630db1f Mon Sep 17 00:00:00 2001 From: piotrekkr Date: Tue, 21 Apr 2020 08:46:03 +0200 Subject: [PATCH 5/8] Fix dead link to DBAL docs --- Resources/doc/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/doc/configuration.rst b/Resources/doc/configuration.rst index fc5e86cd1..47f945691 100644 --- a/Resources/doc/configuration.rst +++ b/Resources/doc/configuration.rst @@ -1133,4 +1133,4 @@ which is the first one defined or the one configured via the Each connection is also accessible via the ``doctrine.dbal.[name]_connection`` service where ``[name]`` is the name of the connection. -.. _DBAL documentation: http://www.doctrine-project.org/docs/dbal/2.0/en +.. _DBAL documentation: https://www.doctrine-project.org/projects/doctrine-dbal/en/2.10/index.html From 65bb2ebc96bcb9207ee56bb17f6c0251ec358380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Thu, 23 Apr 2020 12:38:48 +0200 Subject: [PATCH 6/8] Fix CS --- .../DoctrineExtensionTest.php | 11 ++-- Tests/ServiceRepositoryTest.php | 25 +++++----- Tests/TestCase.php | 50 ++++++++++--------- 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/Tests/DependencyInjection/DoctrineExtensionTest.php b/Tests/DependencyInjection/DoctrineExtensionTest.php index eb1e426ec..65015c863 100644 --- a/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -355,13 +355,14 @@ public function testUseSavePointsAddMethodCallToAddSavepointsToTheConnection() $container = $this->getContainer(); $extension = new DoctrineExtension(); - $extension->load([[ - 'dbal' => [ - 'connections' => [ - 'default' => ['password' => 'foo', 'use_savepoints' => true], + $extension->load([ + [ + 'dbal' => [ + 'connections' => [ + 'default' => ['password' => 'foo', 'use_savepoints' => true], + ], ], ], - ], ], $container); $calls = $container->getDefinition('doctrine.dbal.default_connection')->getMethodCalls(); diff --git a/Tests/ServiceRepositoryTest.php b/Tests/ServiceRepositoryTest.php index 309e28138..8d4c116e2 100644 --- a/Tests/ServiceRepositoryTest.php +++ b/Tests/ServiceRepositoryTest.php @@ -50,21 +50,22 @@ public function testRepositoryServiceWiring() $extension = new DoctrineExtension(); $container->registerExtension($extension); - $extension->load([[ - 'dbal' => [ - 'driver' => 'pdo_sqlite', - 'charset' => 'UTF8', - ], - 'orm' => [ - 'mappings' => [ - 'RepositoryServiceBundle' => [ - 'type' => 'annotation', - 'dir' => __DIR__ . '/DependencyInjection/Fixtures/Bundles/RepositoryServiceBundle/Entity', - 'prefix' => 'Fixtures\Bundles\RepositoryServiceBundle\Entity', + $extension->load([ + [ + 'dbal' => [ + 'driver' => 'pdo_sqlite', + 'charset' => 'UTF8', + ], + 'orm' => [ + 'mappings' => [ + 'RepositoryServiceBundle' => [ + 'type' => 'annotation', + 'dir' => __DIR__ . '/DependencyInjection/Fixtures/Bundles/RepositoryServiceBundle/Entity', + 'prefix' => 'Fixtures\Bundles\RepositoryServiceBundle\Entity', + ], ], ], ], - ], ], $container); $def = $container->register(TestCustomServiceRepoRepository::class, TestCustomServiceRepoRepository::class) diff --git a/Tests/TestCase.php b/Tests/TestCase.php index 93df40bda..721c67559 100644 --- a/Tests/TestCase.php +++ b/Tests/TestCase.php @@ -32,38 +32,40 @@ public function createXmlBundleTestContainer() $extension = new DoctrineExtension(); $container->registerExtension($extension); - $extension->load([[ - 'dbal' => [ - 'connections' => [ - 'default' => [ - 'driver' => 'pdo_mysql', - 'charset' => 'UTF8', - 'platform-service' => 'my.platform', + $extension->load([ + [ + 'dbal' => [ + 'connections' => [ + 'default' => [ + 'driver' => 'pdo_mysql', + 'charset' => 'UTF8', + 'platform-service' => 'my.platform', + ], ], - ], - 'default_connection' => 'default', - 'types' => [ - 'test' => [ - 'class' => TestType::class, - 'commented' => false, + 'default_connection' => 'default', + 'types' => [ + 'test' => [ + 'class' => TestType::class, + 'commented' => false, + ], ], ], - ], 'orm' => [ - 'default_entity_manager' => 'default', - 'entity_managers' => [ - 'default' => [ - 'mappings' => [ - 'XmlBundle' => [ - 'type' => 'xml', - 'dir' => __DIR__ . '/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine', - 'prefix' => 'Fixtures\Bundles\XmlBundle\Entity', + 'orm' => [ + 'default_entity_manager' => 'default', + 'entity_managers' => [ + 'default' => [ + 'mappings' => [ + 'XmlBundle' => [ + 'type' => 'xml', + 'dir' => __DIR__ . '/DependencyInjection/Fixtures/Bundles/XmlBundle/Resources/config/doctrine', + 'prefix' => 'Fixtures\Bundles\XmlBundle\Entity', + ], ], ], ], + 'resolve_target_entities' => ['Symfony\Component\Security\Core\User\UserInterface' => 'stdClass'], ], - 'resolve_target_entities' => ['Symfony\Component\Security\Core\User\UserInterface' => 'stdClass'], ], - ], ], $container); $container->setDefinition('my.platform', new Definition('Doctrine\DBAL\Platforms\MySqlPlatform'))->setPublic(true); From 86d2469d6be06d55ad7b9e2f076f6942476f2e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Thu, 21 May 2020 01:39:06 +0200 Subject: [PATCH 7/8] Add minimal compatibility with changes in DBAL 2.11 RunSqlCommand Proper fix would be more involved, relying on interfaces in DBAL to not change, which we cannot assume won't happen at this point. Full, proper fix needs to be done once DBAL 2.11 API is stable. Such fix will probably involve deprecating our current command class as well, since DBAL one has everything our command added on top in past. --- Command/Proxy/RunSqlDoctrineCommand.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Command/Proxy/RunSqlDoctrineCommand.php b/Command/Proxy/RunSqlDoctrineCommand.php index edcc7828f..ff6c3b078 100644 --- a/Command/Proxy/RunSqlDoctrineCommand.php +++ b/Command/Proxy/RunSqlDoctrineCommand.php @@ -21,7 +21,6 @@ protected function configure() $this ->setName('doctrine:query:sql') - ->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command') ->setHelp(<<%command.name% command executes the given SQL query and outputs the results: @@ -29,6 +28,12 @@ protected function configure() php %command.full_name% "SELECT * FROM users" EOT ); + + if ($this->getDefinition()->hasOption('connection')) { + return; + } + + $this->addOption('connection', null, InputOption::VALUE_OPTIONAL, 'The connection to use for this command'); } /** From 83c89b359b04f5b7342f3b6cd4f631840d3c3491 Mon Sep 17 00:00:00 2001 From: Gwalchmei Date: Thu, 7 May 2020 21:56:36 +0200 Subject: [PATCH 8/8] Update comment on the schema_filter key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/doctrine/dbal/issues/3986 The `schema_filter` key does not filter only tables. Co-authored-by: Grégoire Paris --- Resources/doc/configuration.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Resources/doc/configuration.rst b/Resources/doc/configuration.rst index 47f945691..b16ceefc8 100644 --- a/Resources/doc/configuration.rst +++ b/Resources/doc/configuration.rst @@ -96,8 +96,9 @@ Configuration Reference platform_service: ~ auto_commit: ~ - # If set to "/^sf2_/" all tables not prefixed with "sf2_" will be ignored by the schema - # tool. This is for custom tables which should not be altered automatically. + # If set to "/^sf2_/" all tables, and any named objects such as sequences + # not prefixed with "sf2_" will be ignored by the schema tool. + # This is for custom tables which should not be altered automatically. schema_filter: ~ # When true, queries are logged to a "doctrine" monolog channel