/**
  * {@inheritDoc}
  */
 protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
 {
     /* @var $class ClassMetadata */
     /* @var $parent ClassMetadata */
     if ($parent) {
         $class->setInheritanceType($parent->inheritanceType);
         $class->setDiscriminatorColumn($parent->discriminatorColumn);
         $class->setIdGeneratorType($parent->generatorType);
         $this->addInheritedFields($class, $parent);
         $this->addInheritedRelations($class, $parent);
         $this->addInheritedEmbeddedClasses($class, $parent);
         $class->setIdentifier($parent->identifier);
         $class->setVersioned($parent->isVersioned);
         $class->setVersionField($parent->versionField);
         $class->setDiscriminatorMap($parent->discriminatorMap);
         $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
         $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
         if (!empty($parent->customGeneratorDefinition)) {
             $class->setCustomGeneratorDefinition($parent->customGeneratorDefinition);
         }
         if ($parent->isMappedSuperclass) {
             $class->setCustomRepositoryClass($parent->customRepositoryClassName);
         }
     }
     // Invoke driver
     try {
         $this->driver->loadMetadataForClass($class->getName(), $class);
     } catch (ReflectionException $e) {
         throw MappingException::reflectionFailure($class->getName(), $e);
     }
     // If this class has a parent the id generator strategy is inherited.
     // However this is only true if the hierarchy of parents contains the root entity,
     // if it consists of mapped superclasses these don't necessarily include the id field.
     if ($parent && $rootEntityFound) {
         if ($parent->isIdGeneratorSequence()) {
             $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
         } else {
             if ($parent->isIdGeneratorTable()) {
                 $class->tableGeneratorDefinition = $parent->tableGeneratorDefinition;
             }
         }
         if ($parent->generatorType) {
             $class->setIdGeneratorType($parent->generatorType);
         }
         if ($parent->idGenerator) {
             $class->setIdGenerator($parent->idGenerator);
         }
     } else {
         $this->completeIdGeneratorMapping($class);
     }
     if (!$class->isMappedSuperclass) {
         foreach ($class->embeddedClasses as $property => $embeddableClass) {
             if (isset($embeddableClass['inherited'])) {
                 continue;
             }
             if (isset($this->embeddablesActiveNesting[$embeddableClass['class']])) {
                 throw MappingException::infiniteEmbeddableNesting($class->name, $property);
             }
             $this->embeddablesActiveNesting[$class->name] = true;
             $embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
             if ($embeddableMetadata->isEmbeddedClass) {
                 $this->addNestedEmbeddedClasses($embeddableMetadata, $class, $property);
             }
             $class->inlineEmbeddable($property, $embeddableMetadata);
             unset($this->embeddablesActiveNesting[$class->name]);
         }
     }
     if ($parent && $parent->isInheritanceTypeSingleTable()) {
         $class->setPrimaryTable($parent->table);
     }
     if ($parent && $parent->cache) {
         $class->cache = $parent->cache;
     }
     if ($parent && $parent->containsForeignIdentifier) {
         $class->containsForeignIdentifier = true;
     }
     if ($parent && !empty($parent->namedQueries)) {
         $this->addInheritedNamedQueries($class, $parent);
     }
     if ($parent && !empty($parent->namedNativeQueries)) {
         $this->addInheritedNamedNativeQueries($class, $parent);
     }
     if ($parent && !empty($parent->sqlResultSetMappings)) {
         $this->addInheritedSqlResultSetMappings($class, $parent);
     }
     if ($parent && !empty($parent->entityListeners) && empty($class->entityListeners)) {
         $class->entityListeners = $parent->entityListeners;
     }
     $class->setParentClasses($nonSuperclassParents);
     if ($class->isRootEntity() && !$class->isInheritanceTypeNone() && !$class->discriminatorMap) {
         $this->addDefaultDiscriminatorMap($class);
     }
     if ($this->evm->hasListeners(Events::loadClassMetadata)) {
         $eventArgs = new LoadClassMetadataEventArgs($class, $this->em);
         $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
     }
     $this->validateRuntimeMetadata($class, $parent);
 }
 /**
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  */
 protected function initialize($metadata)
 {
     $dict1GrpCfg = $this->createEntityConfig('grouping', 'Acme\\TestBundle\\Entity\\Dictionary1', ['groups' => [GroupingScope::GROUP_DICTIONARY]]);
     $dict1Cfg = $this->createEntityConfig('dictionary', 'Acme\\TestBundle\\Entity\\Dictionary1', ['virtual_fields' => ['name']]);
     $dict2GrpCfg = $this->createEntityConfig('grouping', 'Acme\\TestBundle\\Entity\\Dictionary2', ['groups' => [GroupingScope::GROUP_DICTIONARY]]);
     $dict2Cfg = $this->createEntityConfig('dictionary', 'Acme\\TestBundle\\Entity\\Dictionary2', ['virtual_fields' => ['id', 'name']]);
     $dict3GrpCfg = $this->createEntityConfig('grouping', 'Acme\\TestBundle\\Entity\\Dictionary3', ['groups' => [GroupingScope::GROUP_DICTIONARY]]);
     $dict3Cfg = $this->createEntityConfig('dictionary', 'Acme\\TestBundle\\Entity\\Dictionary3');
     $dict4GrpCfg = $this->createEntityConfig('grouping', 'Acme\\TestBundle\\Entity\\Dictionary4', ['groups' => [GroupingScope::GROUP_DICTIONARY]]);
     $dict4Cfg = $this->createEntityConfig('dictionary', 'Acme\\TestBundle\\Entity\\Dictionary4');
     $this->groupingConfigProvider->expects($this->any())->method('getConfigs')->will($this->returnValue([$dict1GrpCfg, $dict2GrpCfg, $dict3GrpCfg, $dict4GrpCfg]));
     $this->dictionaryConfigProvider->expects($this->any())->method('hasConfig')->will($this->returnCallback(function ($className, $fieldName) {
         return in_array($className, ['Acme\\TestBundle\\Entity\\Dictionary1', 'Acme\\TestBundle\\Entity\\Dictionary2', 'Acme\\TestBundle\\Entity\\Dictionary3', 'Acme\\TestBundle\\Entity\\Dictionary4']);
     }));
     $this->dictionaryConfigProvider->expects($this->any())->method('getConfig')->will($this->returnCallback(function ($className, $fieldName) use(&$dict1Cfg, &$dict2Cfg, &$dict3Cfg, &$dict4Cfg) {
         switch ($className) {
             case 'Acme\\TestBundle\\Entity\\Dictionary1':
                 return $dict1Cfg;
             case 'Acme\\TestBundle\\Entity\\Dictionary2':
                 return $dict2Cfg;
             case 'Acme\\TestBundle\\Entity\\Dictionary3':
                 return $dict3Cfg;
             case 'Acme\\TestBundle\\Entity\\Dictionary4':
                 return $dict4Cfg;
             default:
                 throw new RuntimeException(sprintf('Entity "%s" is not configurable', $className));
         }
     }));
     $mDataDict1 = $this->createDictionaryMetadata();
     $mDataDict2 = $this->createDictionaryMetadata();
     $mDataDict3 = $this->createDictionaryMetadata();
     $mDataDict4 = $this->createDictionaryMetadata(['name' => 'string', 'code' => 'string', 'label' => 'string'], 'name');
     $this->em->expects($this->any())->method('getClassMetadata')->will($this->returnCallback(function ($className) use(&$metadata, &$mDataDict1, &$mDataDict2, &$mDataDict3, &$mDataDict4) {
         switch ($className) {
             case 'Acme\\TestBundle\\Entity\\Dictionary1':
                 return $mDataDict1;
             case 'Acme\\TestBundle\\Entity\\Dictionary2':
                 return $mDataDict2;
             case 'Acme\\TestBundle\\Entity\\Dictionary3':
                 return $mDataDict3;
             case 'Acme\\TestBundle\\Entity\\Dictionary4':
                 return $mDataDict4;
             default:
                 if (isset($metadata[$className])) {
                     return $metadata[$className];
                 }
                 throw MappingException::reflectionFailure($className, new \ReflectionException());
         }
     }));
 }
 /**
  * Loads the metadata of the class in question and all it's ancestors whose metadata
  * is still not loaded.
  *
  * @param string $name The name of the class for which the metadata should get loaded.
  * @param array  $tables The metadata collection to which the loaded metadata is added.
  */
 protected function loadMetadata($name)
 {
     if (!$this->initialized) {
         $this->initialize();
     }
     $loaded = array();
     $parentClasses = $this->getParentClasses($name);
     $parentClasses[] = $name;
     // Move down the hierarchy of parent classes, starting from the topmost class
     $parent = null;
     $rootEntityFound = false;
     $visited = array();
     foreach ($parentClasses as $className) {
         if (isset($this->loadedMetadata[$className])) {
             $parent = $this->loadedMetadata[$className];
             if (!$parent->isMappedSuperclass) {
                 $rootEntityFound = true;
                 array_unshift($visited, $className);
             }
             continue;
         }
         $class = $this->newClassMetadataInstance($className);
         if ($parent) {
             $class->setInheritanceType($parent->inheritanceType);
             $class->setDiscriminatorColumn($parent->discriminatorColumn);
             $class->setIdGeneratorType($parent->generatorType);
             $this->addInheritedFields($class, $parent);
             $this->addInheritedRelations($class, $parent);
             $class->setIdentifier($parent->identifier);
             $class->setVersioned($parent->isVersioned);
             $class->setVersionField($parent->versionField);
             $class->setDiscriminatorMap($parent->discriminatorMap);
             $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
             $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
         }
         // Invoke driver
         try {
             $this->driver->loadMetadataForClass($className, $class);
         } catch (ReflectionException $e) {
             throw MappingException::reflectionFailure($className, $e);
         }
         // If this class has a parent the id generator strategy is inherited.
         // However this is only true if the hierachy of parents contains the root entity,
         // if it consinsts of mapped superclasses these don't necessarily include the id field.
         if ($parent && $rootEntityFound) {
             if ($parent->isIdGeneratorSequence()) {
                 $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
             } else {
                 if ($parent->isIdGeneratorTable()) {
                     $class->getTableGeneratorDefinition($parent->tableGeneratorDefinition);
                 }
             }
             if ($parent->generatorType) {
                 $class->setIdGeneratorType($parent->generatorType);
             }
             if ($parent->idGenerator) {
                 $class->setIdGenerator($parent->idGenerator);
             }
         } else {
             $this->completeIdGeneratorMapping($class);
         }
         if ($parent && $parent->isInheritanceTypeSingleTable()) {
             $class->setPrimaryTable($parent->table);
         }
         $class->setParentClasses($visited);
         if ($this->evm->hasListeners(Events::loadClassMetadata)) {
             $eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class, $this->em);
             $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
         }
         // Verify & complete identifier mapping
         if (!$class->identifier && !$class->isMappedSuperclass) {
             throw MappingException::identifierRequired($className);
         }
         // verify inheritance
         if (!$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
             if (!$parent) {
                 if (count($class->discriminatorMap) == 0) {
                     throw MappingException::missingDiscriminatorMap($class->name);
                 }
                 if (!$class->discriminatorColumn) {
                     throw MappingException::missingDiscriminatorColumn($class->name);
                 }
             } else {
                 if ($parent && !$class->reflClass->isAbstract() && !in_array($class->name, array_values($class->discriminatorMap))) {
                     // enforce discriminator map for all entities of an inheritance hierachy, otherwise problems will occur.
                     throw MappingException::mappedClassNotPartOfDiscriminatorMap($class->name, $class->rootEntityName);
                 }
             }
         } else {
             if ($class->isMappedSuperclass && $class->name == $class->rootEntityName && (count($class->discriminatorMap) || $class->discriminatorColumn)) {
                 // second condition is necessary for mapped superclasses in the middle of an inheritance hierachy
                 throw MappingException::noInheritanceOnMappedSuperClass($class->name);
             }
         }
         $this->loadedMetadata[$className] = $class;
         $parent = $class;
         if (!$class->isMappedSuperclass) {
             $rootEntityFound = true;
             array_unshift($visited, $className);
         }
         $loaded[] = $className;
     }
     return $loaded;
 }
 /**
  * Loads the metadata of the class in question and all it's ancestors whose metadata
  * is still not loaded.
  *
  * @param string $name The name of the class for which the metadata should get loaded.
  * @param array  $tables The metadata collection to which the loaded metadata is added.
  */
 protected function loadMetadata($name)
 {
     if (!$this->initialized) {
         $this->initialize();
     }
     $loaded = array();
     $parentClasses = $this->getParentClasses($name);
     $parentClasses[] = $name;
     // Move down the hierarchy of parent classes, starting from the topmost class
     $parent = null;
     $rootEntityFound = false;
     $visited = array();
     foreach ($parentClasses as $className) {
         if (isset($this->loadedMetadata[$className])) {
             $parent = $this->loadedMetadata[$className];
             if (!$parent->isMappedSuperclass) {
                 $rootEntityFound = true;
                 array_unshift($visited, $className);
             }
             continue;
         }
         $class = $this->newClassMetadataInstance($className);
         if ($parent) {
             $class->setInheritanceType($parent->inheritanceType);
             $class->setDiscriminatorColumn($parent->discriminatorColumn);
             $class->setIdGeneratorType($parent->generatorType);
             $this->addInheritedFields($class, $parent);
             $this->addInheritedRelations($class, $parent);
             $class->setIdentifier($parent->identifier);
             $class->setVersioned($parent->isVersioned);
             $class->setVersionField($parent->versionField);
             $class->setDiscriminatorMap($parent->discriminatorMap);
             $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
             $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
         }
         // Invoke driver
         try {
             $this->driver->loadMetadataForClass($className, $class);
         } catch (ReflectionException $e) {
             throw MappingException::reflectionFailure($className, $e);
         }
         // If this class has a parent the id generator strategy is inherited.
         // However this is only true if the hierachy of parents contains the root entity,
         // if it consinsts of mapped superclasses these don't necessarily include the id field.
         if ($parent && $rootEntityFound) {
             if ($parent->isIdGeneratorSequence()) {
                 $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
             } else {
                 if ($parent->isIdGeneratorTable()) {
                     $class->getTableGeneratorDefinition($parent->tableGeneratorDefinition);
                 }
             }
             if ($parent->generatorType) {
                 $class->setIdGeneratorType($parent->generatorType);
             }
             if ($parent->idGenerator) {
                 $class->setIdGenerator($parent->idGenerator);
             }
         } else {
             $this->completeIdGeneratorMapping($class);
         }
         if ($parent && $parent->isInheritanceTypeSingleTable()) {
             $class->setPrimaryTable($parent->table);
         }
         if ($parent && $parent->containsForeignIdentifier) {
             $class->containsForeignIdentifier = true;
         }
         $class->setParentClasses($visited);
         if ($this->evm->hasListeners(Events::loadClassMetadata)) {
             $eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class, $this->em);
             $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
         }
         $this->validateRuntimeMetadata($class, $parent);
         $this->loadedMetadata[$className] = $class;
         $parent = $class;
         if (!$class->isMappedSuperclass) {
             $rootEntityFound = true;
             array_unshift($visited, $className);
         }
         $loaded[] = $className;
     }
     return $loaded;
 }
 /**
  * Loads the metadata of the class in question and all it's ancestors whose metadata
  * is still not loaded.
  *
  * @param string $name The name of the class for which the metadata should get loaded.
  * @param array  $tables The metadata collection to which the loaded metadata is added.
  */
 protected function loadMetadata($name)
 {
     if (!$this->initialized) {
         $this->initialize();
     }
     $loaded = array();
     $parentClasses = $this->getParentClasses($name);
     $parentClasses[] = $name;
     // Move down the hierarchy of parent classes, starting from the topmost class
     $parent = null;
     $visited = array();
     foreach ($parentClasses as $className) {
         if (isset($this->loadedMetadata[$className])) {
             $parent = $this->loadedMetadata[$className];
             if (!$parent->isMappedSuperclass) {
                 array_unshift($visited, $className);
             }
             continue;
         }
         $class = $this->newClassMetadataInstance($className);
         if ($parent) {
             $class->setInheritanceType($parent->inheritanceType);
             $class->setDiscriminatorColumn($parent->discriminatorColumn);
             $class->setIdGeneratorType($parent->generatorType);
             $this->addInheritedFields($class, $parent);
             $this->addInheritedRelations($class, $parent);
             $class->setIdentifier($parent->identifier);
             $class->setVersioned($parent->isVersioned);
             $class->setVersionField($parent->versionField);
             $class->setDiscriminatorMap($parent->discriminatorMap);
             $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
             $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
         }
         // Invoke driver
         try {
             $this->driver->loadMetadataForClass($className, $class);
         } catch (ReflectionException $e) {
             throw MappingException::reflectionFailure($className, $e);
         }
         // Verify & complete identifier mapping
         if (!$class->identifier && !$class->isMappedSuperclass) {
             throw MappingException::identifierRequired($className);
         }
         if ($parent && !$parent->isMappedSuperclass) {
             if ($parent->isIdGeneratorSequence()) {
                 $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
             } else {
                 if ($parent->isIdGeneratorTable()) {
                     $class->getTableGeneratorDefinition($parent->tableGeneratorDefinition);
                 }
             }
             if ($parent->generatorType) {
                 $class->setIdGeneratorType($parent->generatorType);
             }
             if ($parent->idGenerator) {
                 $class->setIdGenerator($parent->idGenerator);
             }
         } else {
             $this->completeIdGeneratorMapping($class);
         }
         if ($parent && $parent->isInheritanceTypeSingleTable()) {
             $class->setPrimaryTable($parent->table);
         }
         $class->setParentClasses($visited);
         if ($this->evm->hasListeners(Events::loadClassMetadata)) {
             $eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class);
             $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
         }
         // verify inheritance
         if (!$parent && !$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
             if (count($class->discriminatorMap) == 0) {
                 throw MappingException::missingDiscriminatorMap($class->name);
             }
             if (!$class->discriminatorColumn) {
                 throw MappingException::missingDiscriminatorColumn($class->name);
             }
         }
         $this->loadedMetadata[$className] = $class;
         $parent = $class;
         if (!$class->isMappedSuperclass) {
             array_unshift($visited, $className);
         }
         $loaded[] = $className;
     }
     return $loaded;
 }
 /**
  * Loads the metadata of the class in question and all it's ancestors whose metadata
  * is still not loaded.
  *
  * @param string $name The name of the class for which the metadata should get loaded.
  * @param array  $tables The metadata collection to which the loaded metadata is added.
  */
 protected function _loadMetadata($name)
 {
     if (!$this->_initialized) {
         $this->_initialize();
     }
     $loaded = array();
     // Collect parent classes, ignoring transient (not-mapped) classes.
     //TODO: Evaluate whether we can use class_parents() here.
     $parentClass = $name;
     $parentClasses = array();
     while ($parentClass = get_parent_class($parentClass)) {
         if (!$this->_driver->isTransient($parentClass)) {
             $parentClasses[] = $parentClass;
         }
     }
     $parentClasses = array_reverse($parentClasses);
     $parentClasses[] = $name;
     // Move down the hierarchy of parent classes, starting from the topmost class
     $parent = null;
     $visited = array();
     foreach ($parentClasses as $className) {
         if (isset($this->_loadedMetadata[$className])) {
             $parent = $this->_loadedMetadata[$className];
             if (!$parent->isMappedSuperclass) {
                 array_unshift($visited, $className);
             }
             continue;
         }
         $class = $this->_newClassMetadataInstance($className);
         if ($parent) {
             $class->setInheritanceType($parent->inheritanceType);
             $class->setDiscriminatorColumn($parent->discriminatorColumn);
             $class->setIdGeneratorType($parent->generatorType);
             $this->_addInheritedFields($class, $parent);
             $this->_addInheritedRelations($class, $parent);
             $class->setIdentifier($parent->identifier);
             $class->setVersioned($parent->isVersioned);
             $class->setVersionField($parent->versionField);
             $class->setDiscriminatorMap($parent->discriminatorMap);
             $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
         }
         // Invoke driver
         try {
             $this->_driver->loadMetadataForClass($className, $class);
         } catch (\ReflectionException $e) {
             throw MappingException::reflectionFailure($className, $e);
         }
         // Verify & complete identifier mapping
         if (!$class->identifier && !$class->isMappedSuperclass) {
             throw MappingException::identifierRequired($className);
         }
         if ($parent && !$parent->isMappedSuperclass) {
             if ($parent->isIdGeneratorSequence()) {
                 $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
             } else {
                 if ($parent->isIdGeneratorTable()) {
                     $class->getTableGeneratorDefinition($parent->tableGeneratorDefinition);
                 }
             }
             if ($generatorType = $parent->generatorType) {
                 $class->setIdGeneratorType($generatorType);
             }
             if ($parent->idGenerator) {
                 $class->setIdGenerator($parent->idGenerator);
             }
         } else {
             $this->_completeIdGeneratorMapping($class);
         }
         if ($parent && $parent->isInheritanceTypeSingleTable()) {
             $class->setTableName($parent->getTableName());
         }
         $class->setParentClasses($visited);
         if ($this->_evm->hasListeners(Events::loadClassMetadata)) {
             $eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class);
             $this->_evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
         }
         $this->_loadedMetadata[$className] = $class;
         $parent = $class;
         if (!$class->isMappedSuperclass) {
             array_unshift($visited, $className);
         }
         $loaded[] = $className;
     }
     return $loaded;
 }