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

How to recompute collections in onFlush event? #7685

Open
wtorsi opened this issue Apr 18, 2019 · 4 comments
Open

How to recompute collections in onFlush event? #7685

wtorsi opened this issue Apr 18, 2019 · 4 comments

Comments

@wtorsi
Copy link

wtorsi commented Apr 18, 2019

Hi,
How to recompute changes made for association in onFlush event?
At this moment, i see only one possible solution is to call computeChangeSet on changed parent entity.
But this solution will break when for example parent entity has STATE_NEW, all initial changes will be overwritten.
Documented recomputeSingleEntityChangeSet skips complex associations.

@SenseException
Copy link
Member

Can you please describe your use case in form of code and your complex associations? It sounds like you're having a use case that onFlush isn't capable of. Maybe this is a limit of this event that needs to be written in the documentation or maybe there's a bug. Or you'll get an answer for your question.

@wtorsi
Copy link
Author

wtorsi commented Apr 20, 2019

Sure, here is the code which made changes to collection. I'm awaiting clearing collection cache in commit UOW phase.

public function onFlush(OnFlushEventArgs $args): void
{
    $em = $args->getEntityManager();
    $uow = $em->getUnitOfWork();

    foreach ($uow->getScheduledEntityUpdates() as $entity) {
        if ($entity instanceof Category) {
            /** @var Collection $children */
            $children = $entity->getChildren();
            $child = new Child('test child');
            $children->add($child);
            $em->persist($child);
            $uow->computeChangeSet($child);

            // this will not recompute `children` collection
            $meta = $em->getClassMetadata(Category::class);
            $uow->recomputeSingleEntityChangeSet($meta, $entity);
        }
    }
}

recomputeSingleEntityChangeSet skips collection values by this part of code

    foreach ($class->reflFields as $name => $refProp) {
        if (( ! $class->isIdentifier($name) || ! $class->isIdGeneratorIdentity())
            && ($name !== $class->versionField)
            && ! $class->isCollectionValuedAssociation($name)) {
            $actualData[$name] = $refProp->getValue($entity);
        }
    }

so, only manual clearing is supported.

@SenseException
Copy link
Member

I have to take a look and run your example code on a current version. It looks like it follows the description mentioned in the docs https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html#onflush.

@SenseException
Copy link
Member

@wtorsi I'm able to make one of my example work, but this can be because I miss something that results in this mentioned break in your project.

Can you please create a PR with a failing test to make this reproducible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants