fix: doctrine native lazy objects

This commit is contained in:
2026-09-01 13:58:30 +02:00
parent a60e8357e8
commit 10ab2bd04b
7 changed files with 62 additions and 254 deletions
+3 -3
View File
@@ -10,15 +10,15 @@
} }
], ],
"require": { "require": {
"php": ">=8.2", "php": ">=8.4",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"ext-simplexml": "*", "ext-simplexml": "*",
"ext-sockets": "*", "ext-sockets": "*",
"beberlei/doctrineextensions": "^1.5", "beberlei/doctrineextensions": "^1.5",
"doctrine/doctrine-bundle": "^2.10", "doctrine/doctrine-bundle": "^2.15",
"doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/doctrine-migrations-bundle": "^3.2",
"doctrine/orm": "^2.15", "doctrine/orm": "^3.6",
"flagception/flagception-bundle": "^6.0", "flagception/flagception-bundle": "^6.0",
"knplabs/knp-menu-bundle": "^3.2", "knplabs/knp-menu-bundle": "^3.2",
"knplabs/knp-paginator-bundle": "^6.2", "knplabs/knp-paginator-bundle": "^6.2",
Generated
+39 -238
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "2f83a821022fcd019f4192cff19af85e", "content-hash": "e4ae4ad86c4c01e26d770c2ab3e0fda4",
"packages": [ "packages": [
{ {
"name": "beberlei/doctrineextensions", "name": "beberlei/doctrineextensions",
@@ -360,100 +360,6 @@
}, },
"time": "2024-07-08T12:26:09+00:00" "time": "2024-07-08T12:26:09+00:00"
}, },
{
"name": "doctrine/cache",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
"reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
"shasum": ""
},
"require": {
"php": "~7.1 || ^8.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"cache/integration-tests": "dev-master",
"doctrine/coding-standard": "^9",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"psr/cache": "^1.0 || ^2.0 || ^3.0",
"symfony/cache": "^4.4 || ^5.4 || ^6",
"symfony/var-exporter": "^4.4 || ^5.4 || ^6"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "[email protected]"
},
{
"name": "Roman Borschel",
"email": "[email protected]"
},
{
"name": "Benjamin Eberlei",
"email": "[email protected]"
},
{
"name": "Jonathan Wage",
"email": "[email protected]"
},
{
"name": "Johannes Schmitt",
"email": "[email protected]"
}
],
"description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
"homepage": "https://www.doctrine-project.org/projects/cache.html",
"keywords": [
"abstraction",
"apcu",
"cache",
"caching",
"couchdb",
"memcached",
"php",
"redis",
"xcache"
],
"support": {
"issues": "https://github.com/doctrine/cache/issues",
"source": "https://github.com/doctrine/cache/tree/2.2.0"
},
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
"type": "tidelift"
}
],
"abandoned": true,
"time": "2022-05-20T20:07:39+00:00"
},
{ {
"name": "doctrine/collections", "name": "doctrine/collections",
"version": "2.6.0", "version": "2.6.0",
@@ -540,97 +446,6 @@
], ],
"time": "2026-01-15T10:01:58+00:00" "time": "2026-01-15T10:01:58+00:00"
}, },
{
"name": "doctrine/common",
"version": "3.5.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/common.git",
"reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/common/zipball/d9ea4a54ca2586db781f0265d36bea731ac66ec5",
"reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5",
"shasum": ""
},
"require": {
"doctrine/persistence": "^2.0 || ^3.0 || ^4.0",
"php": "^7.1 || ^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^9.0 || ^10.0",
"doctrine/collections": "^1",
"phpstan/phpstan": "^1.4.1",
"phpstan/phpstan-phpunit": "^1",
"phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0",
"squizlabs/php_codesniffer": "^3.0",
"symfony/phpunit-bridge": "^6.1",
"vimeo/psalm": "^4.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Common\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "[email protected]"
},
{
"name": "Roman Borschel",
"email": "[email protected]"
},
{
"name": "Benjamin Eberlei",
"email": "[email protected]"
},
{
"name": "Jonathan Wage",
"email": "[email protected]"
},
{
"name": "Johannes Schmitt",
"email": "[email protected]"
},
{
"name": "Marco Pivetta",
"email": "[email protected]"
}
],
"description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.",
"homepage": "https://www.doctrine-project.org/projects/common.html",
"keywords": [
"common",
"doctrine",
"php"
],
"support": {
"issues": "https://github.com/doctrine/common/issues",
"source": "https://github.com/doctrine/common/tree/3.5.0"
},
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon",
"type": "tidelift"
}
],
"time": "2025-01-01T22:12:03+00:00"
},
{ {
"name": "doctrine/dbal", "name": "doctrine/dbal",
"version": "3.10.6", "version": "3.10.6",
@@ -1442,61 +1257,49 @@
}, },
{ {
"name": "doctrine/orm", "name": "doctrine/orm",
"version": "2.20.13", "version": "3.6.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/orm.git", "url": "https://github.com/doctrine/orm.git",
"reference": "f525f32e11efc60a34f5eecd88093f476c90f90e" "reference": "a4d13ed5b11e7f7b4d654b1adf95432031ae3ffc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/orm/zipball/f525f32e11efc60a34f5eecd88093f476c90f90e", "url": "https://api.github.com/repos/doctrine/orm/zipball/a4d13ed5b11e7f7b4d654b1adf95432031ae3ffc",
"reference": "f525f32e11efc60a34f5eecd88093f476c90f90e", "reference": "a4d13ed5b11e7f7b4d654b1adf95432031ae3ffc",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"composer-runtime-api": "^2", "composer-runtime-api": "^2",
"doctrine/cache": "^1.12.1 || ^2.1.1", "doctrine/collections": "^2.2",
"doctrine/collections": "^1.5 || ^2.1", "doctrine/dbal": "^3.8.2 || ^4",
"doctrine/common": "^3.0.3",
"doctrine/dbal": "^2.13.1 || ^3.2",
"doctrine/deprecations": "^0.5.3 || ^1", "doctrine/deprecations": "^0.5.3 || ^1",
"doctrine/event-manager": "^1.2 || ^2", "doctrine/event-manager": "^1.2 || ^2",
"doctrine/inflector": "^1.4 || ^2.0", "doctrine/inflector": "^1.4 || ^2.0",
"doctrine/instantiator": "^1.3 || ^2", "doctrine/instantiator": "^1.3 || ^2",
"doctrine/lexer": "^2 || ^3", "doctrine/lexer": "^3",
"doctrine/persistence": "^2.4 || ^3", "doctrine/persistence": "^3.3.1 || ^4",
"ext-ctype": "*", "ext-ctype": "*",
"php": "^7.1 || ^8.0", "php": "^8.1",
"psr/cache": "^1 || ^2 || ^3", "psr/cache": "^1 || ^2 || ^3",
"symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0 || ^8.0", "symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0",
"symfony/polyfill-php72": "^1.23", "symfony/var-exporter": "^6.3.9 || ^7.0 || ^8.0"
"symfony/polyfill-php80": "^1.16"
},
"conflict": {
"doctrine/annotations": "<1.13 || >= 3.0"
}, },
"require-dev": { "require-dev": {
"doctrine/annotations": "^1.13 || ^2", "doctrine/coding-standard": "^14.0",
"doctrine/coding-standard": "^9.0.2 || ^14.0", "phpbench/phpbench": "^1.0",
"phpbench/phpbench": "^0.16.10 || ^1.0", "phpstan/extension-installer": "^1.4",
"phpstan/extension-installer": "~1.1.0 || ^1.4", "phpstan/phpstan": "2.1.23",
"phpstan/phpstan": "~1.4.10 || 2.1.23", "phpstan/phpstan-deprecation-rules": "^2",
"phpstan/phpstan-deprecation-rules": "^1 || ^2", "phpunit/phpunit": "^10.5.0 || ^11.5",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6",
"psr/log": "^1 || ^2 || ^3", "psr/log": "^1 || ^2 || ^3",
"symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", "symfony/cache": "^5.4 || ^6.2 || ^7.0 || ^8.0"
"symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0",
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0"
}, },
"suggest": { "suggest": {
"ext-deepclone": "Improves performance when not using native lazy objects (Symfony 8.1+)",
"ext-dom": "Provides support for XSD validation for XML mapping files", "ext-dom": "Provides support for XSD validation for XML mapping files",
"symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0"
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
}, },
"bin": [
"bin/doctrine"
],
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@@ -1537,40 +1340,38 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/orm/issues", "issues": "https://github.com/doctrine/orm/issues",
"source": "https://github.com/doctrine/orm/tree/2.20.13" "source": "https://github.com/doctrine/orm/tree/3.6.8"
}, },
"time": "2026-05-25T05:46:05+00:00" "time": "2026-08-05T19:05:32+00:00"
}, },
{ {
"name": "doctrine/persistence", "name": "doctrine/persistence",
"version": "3.4.5", "version": "4.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/persistence.git", "url": "https://github.com/doctrine/persistence.git",
"reference": "703a29d8597336fb75f42eeabcdf3f2863156ca8" "reference": "49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/persistence/zipball/703a29d8597336fb75f42eeabcdf3f2863156ca8", "url": "https://api.github.com/repos/doctrine/persistence/zipball/49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b",
"reference": "703a29d8597336fb75f42eeabcdf3f2863156ca8", "reference": "49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"doctrine/deprecations": "^1",
"doctrine/event-manager": "^1 || ^2", "doctrine/event-manager": "^1 || ^2",
"php": "^7.2 || ^8.0", "php": "^8.1",
"psr/cache": "^1.0 || ^2.0 || ^3.0" "psr/cache": "^1.0 || ^2.0 || ^3.0"
}, },
"conflict": {
"doctrine/common": "<2.10"
},
"require-dev": { "require-dev": {
"doctrine/coding-standard": "^12 || ^14", "doctrine/coding-standard": "^14",
"doctrine/common": "^3.0", "phpstan/phpstan": "2.1.30",
"phpstan/phpstan": "^1 || 2.1.30", "phpstan/phpstan-phpunit": "^2",
"phpstan/phpstan-phpunit": "^1 || ^2", "phpstan/phpstan-strict-rules": "^2",
"phpstan/phpstan-strict-rules": "^1 || ^2", "phpunit/phpunit": "^10.5.58 || ^12",
"phpunit/phpunit": "^8.5.38 || ^9.5", "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0",
"symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0" "symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -1619,7 +1420,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/persistence/issues", "issues": "https://github.com/doctrine/persistence/issues",
"source": "https://github.com/doctrine/persistence/tree/3.4.5" "source": "https://github.com/doctrine/persistence/tree/4.2.0"
}, },
"funding": [ "funding": [
{ {
@@ -1635,7 +1436,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-13T19:29:35+00:00" "time": "2026-04-26T12:12:52+00:00"
}, },
{ {
"name": "doctrine/sql-formatter", "name": "doctrine/sql-formatter",
@@ -15963,7 +15764,7 @@
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": ">=8.2", "php": ">=8.4",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"ext-simplexml": "*", "ext-simplexml": "*",
+1 -4
View File
@@ -7,7 +7,7 @@ doctrine:
# either here or in the DATABASE_URL env var (see .env file) # either here or in the DATABASE_URL env var (see .env file)
#server_version: '15' #server_version: '15'
orm: orm:
auto_generate_proxy_classes: true enable_native_lazy_objects: true
# Keep implicit controller-argument entity resolution on (many actions type-hint # Keep implicit controller-argument entity resolution on (many actions type-hint
# an entity against a matching {id}/{uuid} route param without #[MapEntity]). # an entity against a matching {id}/{uuid} route param without #[MapEntity]).
# Setting this explicitly silences the "default will flip to false" deprecation; # Setting this explicitly silences the "default will flip to false" deprecation;
@@ -15,7 +15,6 @@ doctrine:
# migrated to #[MapEntity], which is its own task. # migrated to #[MapEntity], which is its own task.
controller_resolver: controller_resolver:
auto_mapping: true auto_mapping: true
enable_lazy_ghost_objects: true
report_fields_where_declared: true report_fields_where_declared: true
validate_xml_mapping: true validate_xml_mapping: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
@@ -42,8 +41,6 @@ when@test:
when@prod: when@prod:
doctrine: doctrine:
orm: orm:
auto_generate_proxy_classes: false
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
query_cache_driver: query_cache_driver:
type: pool type: pool
pool: doctrine.system_cache_pool pool: doctrine.system_cache_pool
+5
View File
@@ -103,6 +103,7 @@ task('deploy', [
'deploy:lock', 'deploy:lock',
'deploy:release', 'deploy:release',
'deploy:assets', 'deploy:assets',
'deploy:check-platform',
'rsync', 'rsync',
'deploy:shared', 'deploy:shared',
'deploy:writable', 'deploy:writable',
@@ -113,6 +114,10 @@ task('deploy', [
'deploy:stop-workers', 'deploy:stop-workers',
]); ]);
task('deploy:check-platform', function () {
runLocally('composer check-platform-reqs');
});
task('deploy:stop-workers', function () { task('deploy:stop-workers', function () {
run('{{bin/console}} messenger:stop-workers'); run('{{bin/console}} messenger:stop-workers');
}); });
+6 -1
View File
@@ -54,7 +54,12 @@ Why each part is the way it is:
explicitly for both hosts, because the host's default CLI is not the right one. Cron's explicitly for both hosts, because the host's default CLI is not the right one. Cron's
`PATH` is typically only `/usr/bin:/bin`. `vendor/` is rsynced from a developer machine `PATH` is typically only `/usr/bin:/bin`. `vendor/` is rsynced from a developer machine
and there is no `deploy:vendors`, so the CLI must match the PHP the dependencies were and there is no `deploy:vendors`, so the CLI must match the PHP the dependencies were
installed against (8.3). installed against (8.4). Deployments run `composer check-platform-reqs` locally before
rsync; because `config.platform.php` is pinned in `composer.json`, this only verifies
that the locked dependencies resolve against the PHP and extension set we target — it
does not probe the staging or production runtime. Keeping both FPM and
`/usr/local/bin/php` on staging and production at PHP 8.4 is a manual precondition of
every deploy.
- **`--time-limit=300`** on the mailing worker. An 800-recipient mailing needs roughly - **`--time-limit=300`** on the mailing worker. An 800-recipient mailing needs roughly
200360 seconds of worker time — the fan-out renders 800 Twig bodies and inserts 800 200360 seconds of worker time — the fan-out renders 800 Twig bodies and inserts 800
rows, then the mails go out at about 35 per second over a reused SMTP connection. So a rows, then the mails go out at about 35 per second over a reused SMTP connection. So a
+5 -5
View File
@@ -14,7 +14,7 @@ use App\Entity\Embeddable\Communication;
use App\Entity\Teamer; use App\Entity\Teamer;
use App\Entity\User; use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ObjectRepository; use Doctrine\ORM\EntityRepository;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@@ -511,7 +511,7 @@ class UserDataHandlerTest extends TestCase
$profileResponse = $this->createProfileResponse(); $profileResponse = $this->createProfileResponse();
$repository = $this->createMock(ObjectRepository::class); $repository = $this->createMock(EntityRepository::class);
$repository $repository
->expects($this->once()) ->expects($this->once())
->method('findOneBy') ->method('findOneBy')
@@ -562,7 +562,7 @@ class UserDataHandlerTest extends TestCase
$profileResponse = $this->createProfileResponse(); $profileResponse = $this->createProfileResponse();
$repository = $this->createMock(ObjectRepository::class); $repository = $this->createMock(EntityRepository::class);
$repository $repository
->expects($this->once()) ->expects($this->once())
->method('findOneBy') ->method('findOneBy')
@@ -607,7 +607,7 @@ class UserDataHandlerTest extends TestCase
$profileResponse = $this->createProfileResponse(null, null); $profileResponse = $this->createProfileResponse(null, null);
$repository = $this->createMock(ObjectRepository::class); $repository = $this->createMock(EntityRepository::class);
$repository $repository
->expects($this->once()) ->expects($this->once())
->method('findOneBy') ->method('findOneBy')
@@ -669,7 +669,7 @@ class UserDataHandlerTest extends TestCase
$profileResponse = $this->createProfileResponse(); $profileResponse = $this->createProfileResponse();
$repository = $this->createMock(ObjectRepository::class); $repository = $this->createMock(EntityRepository::class);
$repository $repository
->expects($this->once()) ->expects($this->once())
->method('findOneBy') ->method('findOneBy')
+3 -3
View File
@@ -10,7 +10,7 @@ use App\RequiredTeamerCheck\RequiredTeamerCheckRegistry;
use App\Security\MyEpAuthenticator; use App\Security\MyEpAuthenticator;
use App\Security\OAuth2\MyEpClient; use App\Security\OAuth2\MyEpClient;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ObjectRepository; use Doctrine\ORM\EntityRepository;
use Flagception\Manager\FeatureManagerInterface; use Flagception\Manager\FeatureManagerInterface;
use GuzzleHttp\Psr7\Request as Psr7Request; use GuzzleHttp\Psr7\Request as Psr7Request;
use GuzzleHttp\Psr7\Response as Psr7Response; use GuzzleHttp\Psr7\Response as Psr7Response;
@@ -30,7 +30,7 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
class MyEpAuthenticatorTest extends TestCase class MyEpAuthenticatorTest extends TestCase
{ {
private EntityManagerInterface&MockObject $entityManager; private EntityManagerInterface&MockObject $entityManager;
private ObjectRepository&MockObject $repository; private EntityRepository&MockObject $repository;
/** @var User[] */ /** @var User[] */
private array $persisted = []; private array $persisted = [];
@@ -38,7 +38,7 @@ class MyEpAuthenticatorTest extends TestCase
protected function setUp(): void protected function setUp(): void
{ {
$this->persisted = []; $this->persisted = [];
$this->repository = $this->createMock(ObjectRepository::class); $this->repository = $this->createMock(EntityRepository::class);
$this->entityManager = $this->createMock(EntityManagerInterface::class); $this->entityManager = $this->createMock(EntityManagerInterface::class);
$this->entityManager->method('getRepository')->willReturn($this->repository); $this->entityManager->method('getRepository')->willReturn($this->repository);
$this->entityManager $this->entityManager