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

ReferencesListener not calling preUpdate #1152

Closed
webdevilopers opened this issue Sep 10, 2014 · 18 comments
Closed

ReferencesListener not calling preUpdate #1152

webdevilopers opened this issue Sep 10, 2014 · 18 comments

Comments

@webdevilopers
Copy link

Since there still seems to be an issue with the orm and odm config for the ReferencesListener - see #821 - I only have configured the odm this way:

services:
#    gedmo.listener.reference.mysql:
#        class: Gedmo\References\ReferencesListener
#        tags:
##            - { name: doctrine.event_subscriber, connection: game }
#            - { name: doctrine.event_subscriber }
#        calls:
#            - [ setAnnotationReader, [ "@annotation_reader" ] ]
#            - [ registerManager, [ 'document', "@doctrine_mongodb.odm.document_manager" ] ]

    gedmo.listener.reference.mongodb:
         class: Gedmo\References\ReferencesListener
         tags:
            - { name: doctrine_mongodb.odm.event_subscriber }
         calls:
            - [ setAnnotationReader, [ "@annotation_reader" ] ]
            - [ registerManager, [ 'entity', "@doctrine.orm.entity_manager" ] ]    

My Payroll Document is linkend to a Branch Entity:

/**
 * @MongoDB\Document
 */
class Payroll
{
    /**
     * @MongoDB\Id
     */
    protected $id;

    /**
     * @Gedmo\ReferenceOne(type="entity", class="Plusquam\Bundle\ContractBundle\Entity\Branch", identifier="branch_id")
     */
    protected $branch;

    /**
     * @MongoDB\Int
     */
    protected $branch_id;

    public function setBranch(Branch $branch)
    {
        $this->branch = $branch;
    }

    public function getBranch()
    {
        return $this->branch;
    }

    public function setBranchId($branchId)
    {
        $this->branch_id = $branchId;
//        $this->branchId = $branchId;
    }

    public function getBranchId()
    {
//        return $this->branchId;
        return $this->branch_id;
    }

I can successfully create a new Document with the Entity relation. But I can't update it:

        $em = $this->getDoctrine()->getEntityManager();

        $branch = $em->getReference('Plusquam\Bundle\ContractBundle\Entity\Branch', 2);

        $payroll = new \Plusquam\Bundle\TimekeepingBundle\Document\Payroll();
        $payroll->setBranch($branch);

        $dm = $this->get('doctrine_mongodb')->getManager();
        $dm->persist($payroll);
        $dm->flush();

        var_dump($payroll);

        $branch = $em->getReference('Plusquam\Bundle\ContractBundle\Entity\Branch', 4);
        $payroll->setBranch($branch);
        $dm->persist($payroll);
        $dm->flush();

        var_dump($payroll);

        $dm->find('Plusquam\Bundle\TimekeepingBundle\Document\Payroll', $payroll->getId());
        $branch = $em->getReference('Plusquam\Bundle\ContractBundle\Entity\Branch', 6);
        $payroll->setBranch($branch);
        $dm->persist($payroll);
        $dm->flush();

        var_dump($payroll);

I added some output to the ReferencesListener methods:

    public function prePersist(EventArgs $eventArgs)
    {echo "CREATE";
        $this->updateReferences($eventArgs);
    }

    public function preUpdate(EventArgs $eventArgs)
    {echo "UPDATE";
        $this->updateReferences($eventArgs);
    }

The prePersist is called but never the preUpdate.

Is a different service config required to make it work for updating?

@webdevilopers
Copy link
Author

In addition I tested events via HasLifecycleCallbacks on my Document:

/**
 * @MongoDB\Document
 * @MongoDB\HasLifecycleCallbacks
 */
class Payroll
{
    /** @MongoDB\PrePersist */
    public function prePersistBranch()
    {
        echo __METHOD__;
        $this->branch_name = $this->getBranch()->getName();
    }

    /** @MongoDB\PreUpdate */
    public function preUpdateBranch()
    {
        echo __METHOD__;
        $this->branch_name = $this->getBranch()->getName();
    }
}

And preUpdateBranch resp. PreUpdate does not seem to be called either.

This also happens without the ReferencesListener. Is this a possible Doctrine MongoDB ODM issue?

@webdevilopers
Copy link
Author

It really looks like a bug:

doctrine/DoctrineMongoDBBundle#230

supposed to be fixed in

doctrine/mongodb-odm#861

and commented by @jmikola in this answer

http://stackoverflow.com/questions/23927996/creating-persisting-new-document-while-preupdate-event-in-doctrine-mongodb

asked by @lazycommit .

@koemeet
Copy link

koemeet commented Nov 8, 2014

Yep, got the same problem here. preUpdate is not called when altering an entity with one to many. Very annoying bug, needs to be fixed!

@jmikola
Copy link
Contributor

jmikola commented Mar 31, 2015

@webdevilopers, @steffenbrem: Can you confirm if doctrine/mongodb-odm#985 fixes this issue?

@webdevilopers
Copy link
Author

Is that PR doctrine/mongodb-odm#985 in dev-master @jmikola ?
Because then it is not fixed yet.

I couldn't find any other branch for https://github.com/doctrine/mongodb-odm/milestones/1.0.0-BETA13.

@jmikola
Copy link
Contributor

jmikola commented Apr 3, 2015

@webdevilopers: Yes, that commit would be in master. I'll make a note in doctrine/mongodb-odm#861 that this still is not fixed.

@malarzm
Copy link
Contributor

malarzm commented Jun 8, 2015

@webdevilopers could you see if doctrine/mongodb-odm#1121 (it's not merged yet) will solve the issue?

@webdevilopers
Copy link
Author

Will try tomorrow @malarzm !

@webdevilopers
Copy link
Author

I copied your UnitOfWork.php file into my current setup (#1152 (comment)) but still the @MongoDB\PreUpdate annotation / event is not being called. @malarzm :(

@malarzm
Copy link
Contributor

malarzm commented Jun 9, 2015

@webdevilopers could you by any chance create a failing test case and PR it to ODM? It would help a lot with debugging

@webdevilopers
Copy link
Author

I will give it a try tomorrow! At the bottom line it's just an assert that the field changed in the preUpdate event has been changed after flush, right?

@malarzm
Copy link
Contributor

malarzm commented Jun 9, 2015

@webdevilopers yes. Also one thing that came to my mind, are you calling $dm->getUnitOfWork()->recomputeSingleDocumentChangeSet($class, $document); after changing the property in event listener?

@webdevilopers
Copy link
Author

No @malarzm , havn't tried that yet.

Before creating a general Test for PR here is a version for my related app:
https://gist.github.com/webdevilopers/66f24f5fff50d0d460f8#file-payrolltest-php

The second test testPreUpdateIsCalledWhenChangingReferenceOneEntityAndAnyField works fine and calls the preUpdate listener. BECAUSE I am changing at least one regular field here (regHrs).

Simply updating the ReferenceOne pointing to an Entity does not call the preUpdate method.

Hope this helps?

Where exactely in my test should I add your suggested method?

        $documentManager->getUnitOfWork()->recomputeSingleDocumentChangeSet(
            'Plusquam\Bundle\TimekeepingBundle\Document\Payroll', $payroll);
        $documentManager->persist($payroll);
        $documentManager->flush();

@malarzm
Copy link
Contributor

malarzm commented Jun 10, 2015

@webdevilopers oh I think ODM is behaving correctly, you are updating only $branch field which is not tracked by ODM since it's not annotated by our mapping. As a quick fix I'd set some ODM mapped field like $branch_id in setBranch() method so ODM's UnitOfWork will notice there is something to be updated.

@malarzm
Copy link
Contributor

malarzm commented Jun 10, 2015

But also please note that I don't know how @Gedmo annotated fields should behave as I have never used these Extensions so above explanation is valid from ODM point of view :)

@webdevilopers
Copy link
Author

Good advice, @malarzm ! I will follow the discussion on the Gedmo Extension on other issues e.g.:

Indeed the ODM itself works fine. This issue is really related to the gedmo reference listener.

@mohamedaymenkarmous
Copy link

This problem exists until now.
When I update only a Gedmo\ReferenceOne attribute and I flush() that object, preUpdate() is not triggered.
But when I update Gedmo\ReferenceOne attribute including another ODM field and I flush() that object, preUpdate() is trigerred.
Is there any workaround ?

@malarzm
Copy link
Contributor

malarzm commented Apr 28, 2019

The workaround is exactly what you wrote: update a field the ODM is aware of so it can trigger a preUpdate event.

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

No branches or pull requests

5 participants