orm: DDC-3218: Argument 3 passed to Doctrine\ORM\Event\PreUpdateEventArgs::__construct() must be of the type array, null given

Jira issue originally created by user lyrixx:

{quote} Argument 3 passed to Doctrine\ORM\Event\PreUpdateEventArgs:😗*construct() must be of the type array, null given, called in /home/greg/dev/product/insight/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 1009 and defined

Stack trace:

[1] PHPUnit_Framework_Error: Argument 3 passed to Doctrine\ORM\Event\PreUpdateEventArgs::__construct() must be of the type array, null given, called in /project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 1009 and defined at n/a in /project/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php line 47

at PHPUnit*Util_ErrorHandler::handleError('4096', 'Argument 3 passed to Doctrine\ORM\Event\PreUpdateEventArgs::_*construct() must be of the type array, null given, called in /project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 1009 and defined', '/project/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php', '47', array('entity' => object(Violation), 'em' => object(EntityManager)))
    in /project/vendor/doctrine/orm/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php line 47

at Doctrine\ORM\Event\PreUpdateEventArgs->**construct(object(Violation), object(EntityManager), null)
    in /project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 1009

at Doctrine\ORM\UnitOfWork->executeUpdates(object(ClassMetadata))
    in /project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 341

at Doctrine\ORM\UnitOfWork->commit(null)
    in /project/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php line 389

at Doctrine\ORM\EntityManager->flush()
    in /project/src/SensioLabs/Bundle/MyBundle/Controller/MyController.php line 127

at SensioLabs\Bundle\MyBundle\Controller\MyController->ignoreAction(object(Request), object(Project), object(Analysis), '4')
    in  line 

at call*user_func*array(array(object(MyController), 'ignoreAction'), array(object(Request), object(Project), object(Analysis), '4'))
    in /project/app/bootstrap.php.cache line 1043

at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
    in /project/app/bootstrap.php.cache line 1015

at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
    in /project/app/bootstrap.php.cache line 1154

at Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle(object(Request), '1', true)
    in /project/app/bootstrap.php.cache line 435

at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
    in /project/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Client.php line 81

at Symfony\Component\HttpKernel\Client->doRequest(object(Request))
    in /project/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Client.php line 111

at Symfony\Bundle\FrameworkBundle\Client->doRequest(object(Request))
    in /project/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Client.php line 319

at Symfony\Component\BrowserKit\Client->request('POST', '/projects/id-foo/analyses/2/rule/4/ignore', array('ignore*rule' => array('comment' => 'Message about why this rule has been ignored', '*token' => 'CxEFTSv4GZQSWYXtRt-eHybaML4z8I0WK1DHiwr8Ih0')))
    in /project/src/SensioLabs/Bundle/MyBundle/Test/Client.php line 489

at SensioLabs\Bundle\MyBundle\Test\Client->ignoreRuleViolations('id-foo', '2', '4', false)
    in /project/src/SensioLabs/Bundle/MyBundle/Tests/Acceptance/ViolationCommentsTest.php line 217

at SensioLabs\Bundle\MyBundle\Tests\Acceptance\ViolationCommentsTest->testDashboardWithCriticalIgnoredRules()
    in  line 

at ReflectionMethod->invokeArgs(object(ViolationCommentsTest), array())
    in /project/vendor/phpunit/phpunit/src/Framework/TestCase.php line 951

at PHPUnit*Framework*TestCase->runTest()
    in /project/vendor/phpunit/phpunit/src/Framework/TestCase.php line 817

at PHPUnit*Framework*TestCase->runBare()
    in /project/vendor/phpunit/phpunit/src/Framework/TestResult.php line 686

at PHPUnit*Framework*TestResult->run(object(ViolationCommentsTest))
    in /project/vendor/phpunit/phpunit/src/Framework/TestCase.php line 753

at PHPUnit*Framework_TestCase->run(object(PHPUnit_Framework*TestResult))
    in /project/vendor/phpunit/phpunit/src/Framework/TestSuite.php line 675

at PHPUnit*Framework_TestSuite->run(object(PHPUnit_Framework*TestResult))
    in /project/vendor/phpunit/phpunit/src/TextUI/TestRunner.php line 426

at PHPUnit*TextUI_TestRunner->doRun(object(PHPUnit_Framework*TestSuite), array('listGroups' => false, 'loader' => null, 'useDefaultConfiguration' => true, 'configuration' => '/project/app/phpunit.xml.dist', 'filter' => 'testDashboardWithCriticalIgnoredRules', 'testSuffixes' => array('Test.php', '.phpt')))
    in /opt/dotfiles/vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php line 176

at PHPUnit*TextUI*Command->run(array('/usr/local/bin/phpunit', '-c', 'app/', '--filter', 'testDashboardWithCriticalIgnoredRules', 'src/SensioLabs/Bundle/MyBundle/Tests/Acceptance/ViolationCommentsTest.php'), true)
    in /opt/dotfiles/vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php line 129

at PHPUnit*TextUI*Command::main()
    in /opt/dotfiles/vendor/phpunit/phpunit/composer/bin/phpunit line 63

{quote}

I fails in this code

    private function executeUpdates($class)
    {
        $className          = $class->name;
        $persister          = $this->getEntityPersister($className);
        $preUpdateInvoke    = $this->listenersInvoker->getSubscribedSystems($class, Events::preUpdate);
        $postUpdateInvoke   = $this->listenersInvoker->getSubscribedSystems($class, Events::postUpdate);

        foreach ($this->entityUpdates as $oid => $entity) {
            if ($this->em->getClassMetadata(get_class($entity))->name !== $className) {
                continue;
            }

            if ($preUpdateInvoke != ListenersInvoker::INVOKE_NONE) {
// => this line
                $this->listenersInvoker->invoke($class, Events::preUpdate, $entity, new PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]), $preUpdateInvoke);
                $this->recomputeSingleEntityChangeSet($class, $entity);
            }

            if ( ! empty($this->entityChangeSets[$oid])) {
                $persister->update($entity);
            }

            unset($this->entityUpdates[$oid]);

            if ($postUpdateInvoke != ListenersInvoker::INVOKE_NONE) {
                $this->listenersInvoker->invoke($class, Events::postUpdate, $entity, new LifecycleEventArgs($entity, $this->em), $postUpdateInvoke);
            }
        }
    }

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 20 (2 by maintainers)

Commits related to this issue

Most upvoted comments

“Would be a good idea to throw a real exception when trying to flush in a flush; Making this mistake better known.”

I came to the same issue today, throwing that exception would help a lot in debugging.

Comment created by dalexandre:

Would be a good idea to throw a real exception when trying to flush in a flush; Making this mistake better known.

Comment created by stof:

Calling flush() inside a Doctrine listener is not a supported Doctrine usage. it means you are trying to nest several flushes inside each other, which can indeed break the unit of work

I have a Log entity which tracks changes in an Item entity. I need to know what changed each time Item is created, updated, deleted. I have an ItemListener entity listener taking care of my Item, I can’t use PostFlush from here. How should I track the changes from my ItemListener ?

Nested flushes are indeed not supported. If anybody wants to give a stab at a nesting check exception+guard, feel free to do so.

Comment created by charlie_wasp:

I ran into the same issue, I wonder, what should I do?

if I use postUpdate Doctrine event to modify the entity after save them to DB, I can’t save additional changes to DB again with flush() in my listener?

Is there an answer on this?

Yes there is, make the changes using DQL. If you use flush inside your listener, you’ll get the flush process started again, and then more listeners. I’m guessing this recursion is why this isn’t supported.

EDIT: You can also create an impediment for the flush to act recursively. By ensuring it’s only run when a field has changed in PreUpdate. OR if you’re using Symfony, use PostFlush as described in this SO - http://stackoverflow.com/questions/16904462/adding-additional-persist-calls-to-preupdate-call-in-symfony-2-1#answer-16906067