Thanks to visit codestin.com
Credit goes to github.com

Skip to content

#5821 Backport #1551 - Fixed support for inverse side second level cache#6159

Merged
Ocramius merged 1 commit into
doctrine:2.5from
nicolas-cajelli:backport-fix-relation-cache-#1551-to-2.5
Dec 12, 2016
Merged

#5821 Backport #1551 - Fixed support for inverse side second level cache#6159
Ocramius merged 1 commit into
doctrine:2.5from
nicolas-cajelli:backport-fix-relation-cache-#1551-to-2.5

Conversation

@nicolas-cajelli
Copy link
Copy Markdown

Just backport of #1551 (discussion on same issue) by @guilhermeblanco .

Related issue: #5821

@Ocramius Ocramius changed the title Fixed support for inverse side second level cache #5821 Backport #1551 - Fixed support for inverse side second level cache Dec 12, 2016
@Ocramius Ocramius self-assigned this Dec 12, 2016
@Ocramius Ocramius added the Bug label Dec 12, 2016
@Ocramius Ocramius added this to the 2.5.6 milestone Dec 12, 2016
@Ocramius
Copy link
Copy Markdown
Member

@nicolas-cajelli thanks for backporting!

@Ocramius Ocramius merged commit 20cb504 into doctrine:2.5 Dec 12, 2016
@ickbinhier
Copy link
Copy Markdown

Come this problem from this merge?

Warning: Invalid argument supplied for foreach() in /var/www-aura/releases/31/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php line 125

Stack Trace

at in vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php at line 125 
         */
        public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
        {
            foreach ($this->getPropertyAnnotations($property) as $annot) {
                if ($annot instanceof $annotationName) {
                    return $annot;
                }


at Elao\ErrorNotifierBundle\Listener\Notifier ->handlePhpError 2, 'Invalid argument supplied for foreach()', '/var/www-aura/releases/31/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php', 125, array('property' => object(ReflectionProperty), 'annotationName' => 'Doctrine\\ORM\\Mapping\\Cache')
in vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php at line 125 
         */
        public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
        {
            foreach ($this->getPropertyAnnotations($property) as $annot) {
                if ($annot instanceof $annotationName) {
                    return $annot;
                }


at Doctrine\Common\Annotations\CachedReader ->getPropertyAnnotation object(ReflectionProperty), 'Doctrine\\ORM\\Mapping\\Cache'
in vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php at line 292 
                $mapping['fieldName'] = $property->getName();
                // Evaluate @Cache annotation
                if (($cacheAnnot = $this->reader->getPropertyAnnotation($property, Mapping\Cache::class)) !== null) {
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults(
                        $mapping['fieldName'],
                        [


at Doctrine\ORM\Mapping\Driver\AnnotationDriver ->loadMetadataForClass 'JMS\\JobQueueBundle\\Entity\\Job', object(ClassMetadata)
in vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php at line 102 
            /* @var $driver MappingDriver */
            foreach ($this->drivers as $namespace => $driver) {
                if (strpos($className, $namespace) === 0) {
                    $driver->loadMetadataForClass($className, $metadata);
                    return;
                }
            }


at Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain ->loadMetadataForClass 'JMS\\JobQueueBundle\\Entity\\Job', object(ClassMetadata)
in vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php at line 151 
            // Invoke driver
            try {
                $this->driver->loadMetadataForClass($class->getName(), $class);
            } catch (ReflectionException $e) {
                throw MappingException::reflectionFailure($class->getName(), $e);
            }


at Doctrine\ORM\Mapping\ClassMetadataFactory ->doLoadMetadata object(ClassMetadata), null, false, array()
in vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php at line 332 
                $class = $this->newClassMetadataInstance($className);
                $this->initializeReflection($class, $reflService);
                $this->doLoadMetadata($class, $parent, $rootEntityFound, $visited);
                $this->loadedMetadata[$className] = $class;


at Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory ->loadMetadata 'JMS\\JobQueueBundle\\Entity\\Job'
in vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php at line 78 
         */
        protected function loadMetadata($name)
        {
            $loaded = parent::loadMetadata($name);
            array_map([$this, 'resolveDiscriminatorValue'], array_map([$this, 'getMetadataFor'], $loaded));


at Doctrine\ORM\Mapping\ClassMetadataFactory ->loadMetadata 'JMS\\JobQueueBundle\\Entity\\Job'
in vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php at line 216 
                        $this->wakeupReflection($cached, $this->getReflectionService());
                    } else {
                        foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
                            $this->cacheDriver->save(
                                $loadedClassName . $this->cacheSalt,
                                $this->loadedMetadata[$loadedClassName],


at Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory ->getMetadataFor 'JMS\\JobQueueBundle\\Entity\\Job'
in vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php at line 283 
         */
        public function getClassMetadata($className)
        {
            return $this->metadataFactory->getMetadataFor($className);
        }
        /**


at Doctrine\ORM\EntityManager ->getClassMetadata 'JMS\\JobQueueBundle\\Entity\\Job'
in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php at line 1740 
            $token = $this->lexer->lookahead;
            $aliasIdentificationVariable = $this->AliasIdentificationVariable();
            $classMetadata = $this->em->getClassMetadata($abstractSchemaName);
            // Building queryComponent
            $queryComponent = [


at Doctrine\ORM\Query\Parser ->RangeVariableDeclaration
in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php at line 1588 
        public function IdentificationVariableDeclaration()
        {
            $joins                    = [];
            $rangeVariableDeclaration = $this->RangeVariableDeclaration();
            $indexBy                  = $this->lexer->isNextToken(Lexer::T_INDEX)
                ? $this->IndexBy()
                : null;


at Doctrine\ORM\Query\Parser ->IdentificationVariableDeclaration
in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php at line 1323 
            $this->match(Lexer::T_FROM);
            $identificationVariableDeclarations = [];
            $identificationVariableDeclarations[] = $this->IdentificationVariableDeclaration();
            while ($this->lexer->isNextToken(Lexer::T_COMMA)) {
                $this->match(Lexer::T_COMMA);


at Doctrine\ORM\Query\Parser ->FromClause
in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php at line 884 
         */
        public function SelectStatement()
        {
            $selectStatement = new AST\SelectStatement($this->SelectClause(), $this->FromClause());
            $selectStatement->whereClause   = $this->lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null;
            $selectStatement->groupByClause = $this->lexer->isNextToken(Lexer::T_GROUP) ? $this->GroupByClause() : null;


at Doctrine\ORM\Query\Parser ->SelectStatement
in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php at line 853 
            switch ($this->lexer->lookahead['type']) {
                case Lexer::T_SELECT:
                    $statement = $this->SelectStatement();
                    break;
                case Lexer::T_UPDATE:


at Doctrine\ORM\Query\Parser ->QueryLanguage
in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php at line 269 
        public function getAST()
        {
            // Parse & build AST
            $AST = $this->QueryLanguage();
            // Process any deferred validations of some nodes in the AST.
            // This also allows post-processing of the AST for modification purposes.


at Doctrine\ORM\Query\Parser ->getAST
in vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php at line 365 
         */
        public function parse()
        {
            $AST = $this->getAST();
            if (($customWalkers = $this->query->getHint(Query::HINT_CUSTOM_TREE_WALKERS)) !== false) {
                $this->customTreeWalkers = $customWalkers;


at Doctrine\ORM\Query\Parser ->parse
in vendor/doctrine/orm/lib/Doctrine/ORM/Query.php at line 281 
            // Cache miss.
            $parser = new Parser($this);
            $this->_parserResult = $parser->parse();
            $queryCache->save($hash, $this->_parserResult, $this->_queryCacheTTL);


at Doctrine\ORM\Query ->_parse
in vendor/doctrine/orm/lib/Doctrine/ORM/Query.php at line 293 
         */
        protected function _doExecute()
        {
            $executor = $this->_parse()->getSqlExecutor();
            if ($this->_queryCacheProfile) {
                $executor->setQueryCacheProfile($this->_queryCacheProfile);


at Doctrine\ORM\Query ->_doExecute
in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php at line 968 
                };
            }
            $stmt = $this->_doExecute();
            if (is_numeric($stmt)) {
                $setCacheEntry($stmt);


at Doctrine\ORM\AbstractQuery ->executeIgnoreQueryCache null, 1
in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php at line 923 
                return $this->executeUsingQueryCache($parameters, $hydrationMode);
            }
            return $this->executeIgnoreQueryCache($parameters, $hydrationMode);
        }
        /**


at Doctrine\ORM\AbstractQuery ->execute null, 1
in vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php at line 726 
         */
        public function getResult($hydrationMode = self::HYDRATE_OBJECT)
        {
            return $this->execute(null, $hydrationMode);
        }
        /**


at Doctrine\ORM\AbstractQuery ->getResult
in vendor/jms/job-queue-bundle/JMS/JobQueueBundle/Command/RunCommand.php at line 394 
            $staleJobs = $this->getEntityManager()->createQuery("SELECT j FROM ".Job::class." j WHERE j.state = :running AND (j.workerName = :worker OR j.workerName IS NULL)")
                ->setParameter('worker', $workerName)
                ->setParameter('running', Job::STATE_RUNNING)
                ->getResult();
            foreach ($staleJobs as $job) {
                // If the original job has retry jobs, then one of them is still in


at JMS\JobQueueBundle\Command\RunCommand ->cleanUpStaleJobs 'aura-6627'
in vendor/jms/job-queue-bundle/JMS/JobQueueBundle/Command/RunCommand.php at line 126 
                $this->output->writeln('Cleaning up stale jobs');
            }
            $this->cleanUpStaleJobs($workerName);
            $this->runJobs(
                $workerName,


at JMS\JobQueueBundle\Command\RunCommand ->execute object(ArgvInput), object(ConsoleOutput)
in vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php at line 255 
            if ($this->code) {
                $statusCode = call_user_func($this->code, $input, $output);
            } else {
                $statusCode = $this->execute($input, $output);
            }
            return is_numeric($statusCode) ? (int) $statusCode : 0;


at Symfony\Component\Console\Command\Command ->run object(ArgvInput), object(ConsoleOutput)
in vendor/symfony/symfony/src/Symfony/Component/Console/Application.php at line 852 
            if ($event->commandShouldRun()) {
                try {
                    $e = null;
                    $exitCode = $command->run($input, $output);
                } catch (\Exception $x) {
                    $e = $x;
                } catch (\Throwable $x) {


at Symfony\Component\Console\Application ->doRunCommand object(RunCommand), object(ArgvInput), object(ConsoleOutput)
in vendor/symfony/symfony/src/Symfony/Component/Console/Application.php at line 191 
            $command = $this->find($name);
            $this->runningCommand = $command;
            $exitCode = $this->doRunCommand($command, $input, $output);
            $this->runningCommand = null;
            return $exitCode;


at Symfony\Component\Console\Application ->doRun object(ArgvInput), object(ConsoleOutput)
in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php at line 80 
            $this->setDispatcher($container->get('event_dispatcher'));
            return parent::doRun($input, $output);
        }
        /**


at Symfony\Bundle\FrameworkBundle\Console\Application ->doRun object(ArgvInput), object(ConsoleOutput)
in vendor/jms/job-queue-bundle/JMS/JobQueueBundle/Console/Application.php at line 45 
            $this->input = $input;
            try {
                $rs = parent::doRun($input, $output);
                $this->saveDebugInformation();
                return $rs;


at JMS\JobQueueBundle\Console\Application ->doRun object(ArgvInput), object(ConsoleOutput)
in vendor/symfony/symfony/src/Symfony/Component/Console/Application.php at line 122 
            $this->configureIO($input, $output);
            try {
                $exitCode = $this->doRun($input, $output);
            } catch (\Exception $e) {
                if (!$this->catchExceptions) {
                    throw $e;


at Symfony\Component\Console\Application ->run object(ArgvInput)
in bin/console at line 28 
    $kernel = new AppKernel($env, $debug);
    $application = new Application($kernel);
    $application->run($input);

@Ocramius
Copy link
Copy Markdown
Member

@ickbinhier can you run the schema validator against your mappings?

@ickbinhier
Copy link
Copy Markdown

thanks.

bin/console doctrine:schema:validate
[Mapping]  OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files.

@ickbinhier
Copy link
Copy Markdown

But the problem still exists.

@Ocramius
Copy link
Copy Markdown
Member

@ickbinhier few things here:

  • try clearing your cache (it's the cached reader that is causing the failure)
  • check whether it's this patch that caused it, or whether switching to 2.5.5 still causes the problem
  • check what composer dependencies were updated (composer.lock changes)

AlexKryvets added a commit to AlexKryvets/doctrine2 that referenced this pull request Dec 23, 2016
This release relaxes [`doctrine/common`](https://github.com/doctrine/common) requirements
in order to allow installation of versions that support PHP 7.1 features in proxy class
generation. Please note that a similar requirement relaxation still needs to be applied to
[`doctrine/dbal`](https://github.com/doctrine/dbal) in order to allow installation of
the latest `doctrine/common` versions. [doctrine#6156](doctrine#6156)

This version also backports some fixes around the eviction of the second level cache entries
of inverse side associations in one-to-many - many-to-one mappings. [doctrine#6159](doctrine#6159)

Further fixes were applied in order to have child classes in inheritance mapping share the
same timestamp region when the second level cache is enabled. [doctrine#6028](doctrine#6028)

Also, `Doctrine\ORM\EntityManager#merge()` now triggers `Doctrine\ORM\Events::prePersist`
listeners with the merged entity state whenever an internal `Doctrine\ORM\UnitOfWork#persist()`
call is implied. [doctrine#6177](doctrine#6177).

Total issues resolved: **8**

- [5570: Fix PrePersist EventListener when using merge instead of persist](doctrine#5570)
- [6028: Make child entity share the timestamp region with parent class](doctrine#6028)
- [6110: Clear $this->collection even when empty, to reset keys](doctrine#6110)
- [6156: Allow doctrine/common 2.7](doctrine#6156)
- [6159: doctrine#5821 Backport doctrine#1551 - Fixed support for inverse side second level cache](doctrine#6159)
- [6174: Merging a new entity with PrePersist event make changes in callback not be considered](doctrine#6174)
- [6177: Fix doctrine#6174 doctrine#5570: merging new entities should also trigger prepersist lifecycle callbacks with merged entity data](doctrine#6177)
- [6178: Backport doctrine#6177 - fix doctrine#6174 doctrine#5570: merging new entities should also trigger prepersist lifecycle callbacks with the merged data](doctrine#6178)

# gpg: directory `/c/Users/PC/.gnupg' created
# gpg: new configuration file `/c/Users/PC/.gnupg/gpg.conf' created
# gpg: WARNING: options in `/c/Users/PC/.gnupg/gpg.conf' are not yet active during this run
# gpg: keyring `/c/Users/PC/.gnupg/pubring.gpg' created
# gpg: Signature made Tue Dec 20 00:49:05 2016 FLEST using DSA key ID 12EC2DF8
# gpg: Can't check signature: public key not found

# Conflicts:
#	lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php
#	lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
#	tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php
#	tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php
#	tests/Doctrine/Tests/ORM/Tools/Pagination/PaginationTestCase.php
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.

4 participants