Skip to content

Commit f2fba56

Browse files
authored
ManagerRegistry: reset also persisters in UnitOfWork (#140)
1 parent d3fe320 commit f2fba56

5 files changed

Lines changed: 86 additions & 19 deletions

File tree

src/DI/Helpers/BuilderMan.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,10 @@ public function getServiceDefinitionsByTag(string $tag): array
9999
$builder = $this->pass->getContainerBuilder();
100100
$definitions = [];
101101

102+
/** @var array{name: string}|string $tagValue */
102103
foreach ($builder->findByTag($tag) as $serviceName => $tagValue) {
103-
$definitions[(string) $tagValue] = $builder->getDefinition($serviceName);
104+
$name = is_array($tagValue) ? $tagValue['name'] : $tagValue;
105+
$definitions[$name] = $builder->getDefinition($serviceName);
104106
}
105107

106108
return $definitions;
@@ -114,8 +116,10 @@ public function getServiceNamesByTag(string $tag): array
114116
$builder = $this->pass->getContainerBuilder();
115117
$definitions = [];
116118

119+
/** @var array{name: string}|string $tagValue */
117120
foreach ($builder->findByTag($tag) as $serviceName => $tagValue) {
118-
$definitions[(string) $tagValue] = $serviceName;
121+
$name = is_array($tagValue) ? $tagValue['name'] : $tagValue;
122+
$definitions[$name] = $serviceName;
119123
}
120124

121125
return $definitions;

src/DI/OrmExtension.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* @property-read stdClass $config
2323
* @phpstan-type TManagerConfig object{
2424
* entityManagerDecoratorClass: string|null,
25-
* configurationClass: string,
25+
* configurationClass: class-string,
2626
* lazyNativeObjects: bool|null,
2727
* proxyDir: string|null,
2828
* autoGenerateProxyClasses: int|bool|Statement,
@@ -86,7 +86,7 @@ public function __construct(
8686
public function getConfigSchema(): Schema
8787
{
8888
$parameters = $this->getContainerBuilder()->parameters;
89-
$proxyDir = isset($parameters['tempDir']) ? $parameters['tempDir'] . '/cache/doctrine/orm/proxies' : null;
89+
$proxyDir = isset($parameters['tempDir']) && is_string($parameters['tempDir']) ? $parameters['tempDir'] . '/cache/doctrine/orm/proxies' : null;
9090
$autoGenerateProxy = boolval($parameters['debugMode'] ?? true);
9191

9292
$expectService = Expect::anyOf(

src/ManagerRegistry.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Nettrine\ORM;
44

55
use Doctrine\ORM\EntityManager;
6+
use Doctrine\ORM\EntityManagerInterface;
7+
use Doctrine\ORM\UnitOfWork;
68
use Doctrine\Persistence\AbstractManagerRegistry;
79
use Doctrine\Persistence\ObjectManagerDecorator;
810
use Doctrine\Persistence\Proxy;
@@ -36,19 +38,30 @@ public function __construct(
3638
);
3739
}
3840

39-
/**
40-
* @param ObjectManagerDecorator<EntityManager>|EntityManager $manager
41-
*/
42-
public static function reopen(ObjectManagerDecorator|EntityManager $manager): void
41+
public static function reopen(EntityManagerInterface $manager): void
4342
{
4443
// @phpcs:disable
4544
Binder::use($manager, function (): void {
4645
if ($this instanceof EntityManager) { // @phpstan-ignore-line
4746
$this->closed = false; // @phpstan-ignore-line
47+
48+
$uow = $this->getUnitOfWork();
49+
Binder::use($uow, function (): void {
50+
if ($this instanceof UnitOfWork) { // @phpstan-ignore-line
51+
$this->persisters = [];
52+
}
53+
});
4854
} elseif ($this instanceof ObjectManagerDecorator) {
4955
Binder::use($this->wrapped, function (): void { // @phpstan-ignore-line
5056
if ($this instanceof EntityManager) { // @phpstan-ignore-line
5157
$this->closed = false;
58+
59+
$uow = $this->getUnitOfWork();
60+
Binder::use($uow, function (): void {
61+
if ($this instanceof UnitOfWork) { // @phpstan-ignore-line
62+
$this->persisters = [];
63+
}
64+
});
5265
}
5366
});
5467
}

tests/Cases/DI/OrmExtension.schemaIgnoreClasses.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php declare(strict_types=1);
1+
<?php declare(strict_types = 1);
22

33
use Contributte\Tester\Toolkit;
44
use Contributte\Tester\Utils\ContainerBuilder;

tests/Cases/ManagerRegistry.phpt

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use Contributte\Tester\Toolkit;
44
use Contributte\Tester\Utils\ContainerBuilder;
55
use Contributte\Tester\Utils\Neonkit;
66
use Doctrine\DBAL\Connection;
7-
use Doctrine\ORM\EntityManager;
7+
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
88
use Doctrine\ORM\EntityManagerInterface;
99
use Doctrine\Persistence\ManagerRegistry;
1010
use Nette\DI\Compiler;
@@ -368,6 +368,7 @@ Toolkit::test(function (): void {
368368
$compiler->addConfig([
369369
'parameters' => [
370370
'tempDir' => Tests::TEMP_PATH,
371+
'fixturesDir' => Tests::FIXTURES_PATH,
371372
],
372373
]);
373374
$compiler->addConfig(Neonkit::load(
@@ -379,30 +380,79 @@ Toolkit::test(function (): void {
379380
password: test
380381
user: test
381382
path: ":memory:"
383+
second:
384+
driver: pdo_sqlite
385+
password: test
386+
user: test
387+
path: ":memory:"
382388
nettrine.orm:
383389
managers:
384390
default:
385391
connection: default
386392
mapping:
387393
App:
388394
type: attributes
389-
directories: [app/Database]
390-
namespace: App\Database
395+
directories: [%fixturesDir%/Entity]
396+
namespace: Tests\Mocks\Entity
397+
second:
398+
connection: second
399+
entityManagerDecoratorClass: Tests\Mocks\DummyEntityManagerDecorator
400+
mapping:
401+
App:
402+
type: attributes
403+
directories: [%fixturesDir%/Entity]
404+
namespace: Tests\Mocks\Entity
391405
NEON
392406
));
393407
})
394408
->build();
395409

396-
/** @var EntityManager $em */
397-
$em = $container->getByType(EntityManagerInterface::class);
410+
/** @var ManagerRegistry $registry */
411+
$registry = $container->getByType(ManagerRegistry::class);
412+
413+
foreach (['default', 'second'] as $managerName) {
414+
/** @var EntityManagerInterface $em */
415+
$em = $registry->getManager($managerName);
416+
Assert::true($em->isOpen());
417+
418+
/** @var Connection $connection */
419+
$connection = $registry->getConnection($managerName);
420+
421+
$connection->executeQuery('CREATE TABLE dummy_entity (id integer primary key autoincrement, username string unique not null)');
422+
423+
$persister1 = $em->getUnitOfWork()->getEntityPersister(DummyEntity::class);
398424

399-
Assert::true($em->isOpen());
400-
$em->close();
401-
Assert::false($em->isOpen());
425+
$em->persist(new DummyEntity('test'));
426+
$em->flush();
402427

403-
NettrineManagerRegistry::reopen($em);
428+
Assert::count(0, $persister1->getInserts(), 'Persister should have no inserts, have ' . count($persister1->getInserts()));
404429

405-
Assert::true($em->isOpen());
430+
// try to create a new entity with the same username - not unique
431+
$em->persist(new DummyEntity('test'));
432+
try {
433+
$em->flush();
434+
} catch (UniqueConstraintViolationException) {
435+
Assert::false($em->isOpen());
436+
}
437+
438+
// after failing queue there is cached last insert
439+
Assert::count(1, $persister1->getInserts(), 'Persister should have 1 insert, have ' . count($persister1->getInserts()));
440+
441+
NettrineManagerRegistry::reopen($em);
442+
443+
Assert::true($em->isOpen());
444+
445+
$persister2 = $em->getUnitOfWork()->getEntityPersister(DummyEntity::class);
446+
447+
// check if the persister is different after reopening
448+
Assert::notSame($persister1, $persister2);
449+
450+
$dummy2 = new DummyEntity('test2');
451+
$em->persist($dummy2);
452+
$em->flush();
453+
454+
Assert::count(2, $em->getRepository(DummyEntity::class)->findAll());
455+
}
406456
});
407457

408458
// Get repository for manager

0 commit comments

Comments
 (0)