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

Fix attach entity listener when reset class metadata factory #10786

Conversation

vuongxuongminh
Copy link
Contributor

When resetting entity manager via registry, if we use Doctrine\ORM\Tools\AttachEntityListenersListener to add entity event listeners, it can not be reattached because it delete listener after add on the first time then we will lose all entity listeners after reset entity manager.

Symfony entity listener example:

<?php

declare(strict_types=1);

namespace App\EntityEventListener;


use App\Entity\Company;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;


#[AsEntityListener(event: 'prePersist', entity: Company::class)]
class CompanyListener
{
    public function prePersist() : void
    {
        echo 'It work!';
    }
}

and console command execution:

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $manager = $this->registry->getManager();
        $company = new Company();
        $company->setText('1');
        $manager->persist($company);
        $manager->flush();

        $this->registry->resetManager(); /// there's the problem

        $company = new Company();
        $company->setText('2');
        $manager->persist($company);
        $manager->flush();


        return 0;
    }

Expect It work! should be printed twice but only once.

@greg0ire greg0ire added the Bug label Jun 22, 2023
greg0ire
greg0ire previously approved these changes Jun 22, 2023
Copy link
Member

@greg0ire greg0ire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found this suspicious at first, but this does not seem to break any tests so…

@@ -56,7 +56,5 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $event)
$metadata->addEntityListener($listener['event'], $listener['class'], $listener['method']);
}
}

unset($this->entityListeners[$metadata->name]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this listener, what it does is attach entity listeners as soon as class metadata is loaded. After that, it considers its job done forever, hence the unset (to save memory I guess).

@greg0ire

This comment was marked as resolved.

@greg0ire greg0ire closed this Jun 27, 2023
@greg0ire greg0ire reopened this Jun 27, 2023
@greg0ire greg0ire added this to the 2.15.4 milestone Jun 27, 2023
@greg0ire greg0ire merged commit dba90c1 into doctrine:2.15.x Jun 27, 2023
@greg0ire
Copy link
Member

Thanks @vuongxuongminh !

@vuongxuongminh vuongxuongminh deleted the fix-attach-entity-listener-when-reset-class-metadata-factory branch December 1, 2023 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants