From 76e4f5a80bf8faa6e00ec4746c34f2e4bfd4215e Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 2 Jan 2012 21:32:18 +0100 Subject: [PATCH] DCOM-93 - Removed reflection dependency from ClassMetadata completly, moving all the code into ClassMetadataInfo for BC reasons. --- lib/Doctrine/ORM/Mapping/ClassMetadata.php | 315 +----------------- .../ORM/Mapping/ClassMetadataFactory.php | 14 +- .../ORM/Mapping/ClassMetadataInfo.php | 292 +++++++++++++++- .../DisconnectedClassMetadataFactory.php | 33 -- .../ORM/Functional/Ticket/DDC168Test.php | 2 +- .../ORM/Mapping/AnnotationDriverTest.php | 2 + .../Tests/ORM/Mapping/ClassMetadataTest.php | 8 +- .../Tests/ORM/Tools/EntityGeneratorTest.php | 6 +- 8 files changed, 308 insertions(+), 364 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadata.php b/lib/Doctrine/ORM/Mapping/ClassMetadata.php index 07c65fd47..70b8f9e40 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadata.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadata.php @@ -20,7 +20,6 @@ namespace Doctrine\ORM\Mapping; use ReflectionClass, ReflectionProperty; -use Doctrine\Common\Persistence\Mapping\ClassMetadata AS IClassMetadata; /** * A ClassMetadata instance holds all the object-relational mapping metadata @@ -40,318 +39,6 @@ use Doctrine\Common\Persistence\Mapping\ClassMetadata AS IClassMetadata; * @author Jonathan H. Wage * @since 2.0 */ -class ClassMetadata extends ClassMetadataInfo implements IClassMetadata +class ClassMetadata extends ClassMetadataInfo { - /** - * The ReflectionProperty instances of the mapped class. - * - * @var array - */ - public $reflFields = array(); - - /** - * The prototype from which new instances of the mapped class are created. - * - * @var object - */ - private $_prototype; - - /** - * Initializes a new ClassMetadata instance that will hold the object-relational mapping - * metadata of the class with the given name. - * - * @param string $entityName The name of the entity class the new instance is used for. - */ - public function initializeReflection($reflService) - { - $this->reflClass = $reflService->getClass($this->name); - $this->namespace = $reflService->getClassNamespace($this->name); - $this->table['name'] = $reflService->getClassShortName($this->name); - - if ($this->reflClass) { - $this->name = $this->rootEntityName = $this->reflClass->getName(); - } - } - - /** - * Gets the ReflectionPropertys of the mapped class. - * - * @return array An array of ReflectionProperty instances. - */ - public function getReflectionProperties() - { - return $this->reflFields; - } - - /** - * Gets a ReflectionProperty for a specific field of the mapped class. - * - * @param string $name - * @return ReflectionProperty - */ - public function getReflectionProperty($name) - { - return $this->reflFields[$name]; - } - - /** - * Gets the ReflectionProperty for the single identifier field. - * - * @return ReflectionProperty - * @throws BadMethodCallException If the class has a composite identifier. - */ - public function getSingleIdReflectionProperty() - { - if ($this->isIdentifierComposite) { - throw new \BadMethodCallException("Class " . $this->name . " has a composite identifier."); - } - return $this->reflFields[$this->identifier[0]]; - } - - /** - * Validates & completes the given field mapping. - * - * @param array $mapping The field mapping to validated & complete. - * @return array The validated and completed field mapping. - * - * @throws MappingException - */ - protected function _validateAndCompleteFieldMapping(array &$mapping) - { - parent::_validateAndCompleteFieldMapping($mapping); - - // Store ReflectionProperty of mapped field - $refProp = $this->reflClass->getProperty($mapping['fieldName']); - $refProp->setAccessible(true); - $this->reflFields[$mapping['fieldName']] = $refProp; - } - - /** - * Validates & completes the basic mapping information that is common to all - * association mappings (one-to-one, many-ot-one, one-to-many, many-to-many). - * - * @param array $mapping The mapping. - * @return array The updated mapping. - * @throws MappingException If something is wrong with the mapping. - */ - protected function _validateAndCompleteAssociationMapping(array $mapping) - { - $mapping = parent::_validateAndCompleteAssociationMapping($mapping); - - if ( ! \Doctrine\Common\ClassLoader::classExists($mapping['targetEntity']) ) { - throw MappingException::invalidTargetEntityClass($mapping['targetEntity'], $this->name, $mapping['fieldName']); - } - - return $mapping; - } - - /** - * Extracts the identifier values of an entity of this class. - * - * For composite identifiers, the identifier values are returned as an array - * with the same order as the field order in {@link identifier}. - * - * @param object $entity - * @return array - */ - public function getIdentifierValues($entity) - { - if ($this->isIdentifierComposite) { - $id = array(); - - foreach ($this->identifier as $idField) { - $value = $this->reflFields[$idField]->getValue($entity); - - if ($value !== null) { - $id[$idField] = $value; - } - } - - return $id; - } - - $value = $this->reflFields[$this->identifier[0]]->getValue($entity); - - if ($value !== null) { - return array($this->identifier[0] => $value); - } - - return array(); - } - - /** - * Populates the entity identifier of an entity. - * - * @param object $entity - * @param mixed $id - * @todo Rename to assignIdentifier() - */ - public function setIdentifierValues($entity, array $id) - { - foreach ($id as $idField => $idValue) { - $this->reflFields[$idField]->setValue($entity, $idValue); - } - } - - /** - * Sets the specified field to the specified value on the given entity. - * - * @param object $entity - * @param string $field - * @param mixed $value - */ - public function setFieldValue($entity, $field, $value) - { - $this->reflFields[$field]->setValue($entity, $value); - } - - /** - * Gets the specified field's value off the given entity. - * - * @param object $entity - * @param string $field - */ - public function getFieldValue($entity, $field) - { - return $this->reflFields[$field]->getValue($entity); - } - - /** - * Stores the association mapping. - * - * @param AssociationMapping $assocMapping - */ - protected function _storeAssociationMapping(array $assocMapping) - { - parent::_storeAssociationMapping($assocMapping); - - // Store ReflectionProperty of mapped field - $sourceFieldName = $assocMapping['fieldName']; - - $refProp = $this->reflClass->getProperty($sourceFieldName); - $refProp->setAccessible(true); - $this->reflFields[$sourceFieldName] = $refProp; - } - - /** - * Creates a string representation of this instance. - * - * @return string The string representation of this instance. - * @todo Construct meaningful string representation. - */ - public function __toString() - { - return __CLASS__ . '@' . spl_object_hash($this); - } - - /** - * Determines which fields get serialized. - * - * It is only serialized what is necessary for best unserialization performance. - * That means any metadata properties that are not set or empty or simply have - * their default value are NOT serialized. - * - * Parts that are also NOT serialized because they can not be properly unserialized: - * - reflClass (ReflectionClass) - * - reflFields (ReflectionProperty array) - * - * @return array The names of all the fields that should be serialized. - */ - public function __sleep() - { - // This metadata is always serialized/cached. - $serialized = array( - 'associationMappings', - 'columnNames', //TODO: Not really needed. Can use fieldMappings[$fieldName]['columnName'] - 'fieldMappings', - 'fieldNames', - 'identifier', - 'isIdentifierComposite', // TODO: REMOVE - 'name', - 'namespace', // TODO: REMOVE - 'table', - 'rootEntityName', - 'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime. - ); - - // The rest of the metadata is only serialized if necessary. - if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) { - $serialized[] = 'changeTrackingPolicy'; - } - - if ($this->customRepositoryClassName) { - $serialized[] = 'customRepositoryClassName'; - } - - if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE) { - $serialized[] = 'inheritanceType'; - $serialized[] = 'discriminatorColumn'; - $serialized[] = 'discriminatorValue'; - $serialized[] = 'discriminatorMap'; - $serialized[] = 'parentClasses'; - $serialized[] = 'subClasses'; - } - - if ($this->generatorType != self::GENERATOR_TYPE_NONE) { - $serialized[] = 'generatorType'; - if ($this->generatorType == self::GENERATOR_TYPE_SEQUENCE) { - $serialized[] = 'sequenceGeneratorDefinition'; - } - } - - if ($this->isMappedSuperclass) { - $serialized[] = 'isMappedSuperclass'; - } - - if ($this->containsForeignIdentifier) { - $serialized[] = 'containsForeignIdentifier'; - } - - if ($this->isVersioned) { - $serialized[] = 'isVersioned'; - $serialized[] = 'versionField'; - } - - if ($this->lifecycleCallbacks) { - $serialized[] = 'lifecycleCallbacks'; - } - - if ($this->namedQueries) { - $serialized[] = 'namedQueries'; - } - - if ($this->isReadOnly) { - $serialized[] = 'isReadOnly'; - } - - return $serialized; - } - - /** - * Creates a new instance of the mapped class, without invoking the constructor. - * - * @return object - */ - public function newInstance() - { - if ($this->_prototype === null) { - $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name)); - } - - return clone $this->_prototype; - } - - /** - * @param string $callback - * @param string $event - */ - public function addLifecycleCallback($callback, $event) - { - if ( !$this->reflClass->hasMethod($callback) || - ($this->reflClass->getMethod($callback)->getModifiers() & \ReflectionMethod::IS_PUBLIC) == 0) { - throw MappingException::lifecycleCallbackMethodNotFound($this->name, $callback); - } - - return parent::addLifecycleCallback($callback, $event); - } } diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 4590b9ee3..0d93b18c9 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -359,11 +359,15 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface */ protected function validateRuntimeMetadata($class, $parent) { - // Verify & complete identifier mapping - if ( ! $class->identifier && ! $class->isMappedSuperclass) { - throw MappingException::identifierRequired($class->name); + if ( ! $class->reflClass ) { + // only validate if there is a reflection class instance + return; } + $class->validateIdentifier(); + $class->validateAssocations(); + $class->validateLifecycleCallbacks($this->getReflectionService()); + // verify inheritance if (!$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) { if (!$parent) { @@ -381,10 +385,6 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface // second condition is necessary for mapped superclasses in the middle of an inheritance hierachy throw MappingException::noInheritanceOnMappedSuperClass($class->name); } - - if ($class->usesIdGenerator() && $class->isIdentifierComposite) { - throw MappingException::compositeKeyAssignedIdGeneratorRequired($class->name); - } } /** diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 82c1adff2..08ce40a64 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -21,6 +21,7 @@ namespace Doctrine\ORM\Mapping; use Doctrine\DBAL\Types\Type; use ReflectionClass; +use Doctrine\Common\Persistence\Mapping\ClassMetadata; /** * A ClassMetadata instance holds all the object-relational mapping metadata @@ -40,7 +41,7 @@ use ReflectionClass; * @author Jonathan H. Wage * @since 2.0 */ -class ClassMetadataInfo +class ClassMetadataInfo implements ClassMetadata { /* The inheritance mapping types */ /** @@ -494,6 +495,20 @@ class ClassMetadataInfo */ public $isReadOnly = false; + /** + * The ReflectionProperty instances of the mapped class. + * + * @var array + */ + public $reflFields = array(); + + /** + * The prototype from which new instances of the mapped class are created. + * + * @var object + */ + private $_prototype; + /** * Initializes a new ClassMetadata instance that will hold the object-relational mapping * metadata of the class with the given name. @@ -506,6 +521,219 @@ class ClassMetadataInfo $this->rootEntityName = $entityName; } + /** + * Gets the ReflectionPropertys of the mapped class. + * + * @return array An array of ReflectionProperty instances. + */ + public function getReflectionProperties() + { + return $this->reflFields; + } + + /** + * Gets a ReflectionProperty for a specific field of the mapped class. + * + * @param string $name + * @return ReflectionProperty + */ + public function getReflectionProperty($name) + { + return $this->reflFields[$name]; + } + + /** + * Gets the ReflectionProperty for the single identifier field. + * + * @return ReflectionProperty + * @throws BadMethodCallException If the class has a composite identifier. + */ + public function getSingleIdReflectionProperty() + { + if ($this->isIdentifierComposite) { + throw new \BadMethodCallException("Class " . $this->name . " has a composite identifier."); + } + return $this->reflFields[$this->identifier[0]]; + } + + /** + * Extracts the identifier values of an entity of this class. + * + * For composite identifiers, the identifier values are returned as an array + * with the same order as the field order in {@link identifier}. + * + * @param object $entity + * @return array + */ + public function getIdentifierValues($entity) + { + if ($this->isIdentifierComposite) { + $id = array(); + + foreach ($this->identifier as $idField) { + $value = $this->reflFields[$idField]->getValue($entity); + + if ($value !== null) { + $id[$idField] = $value; + } + } + + return $id; + } + + $value = $this->reflFields[$this->identifier[0]]->getValue($entity); + + if ($value !== null) { + return array($this->identifier[0] => $value); + } + + return array(); + } + + /** + * Populates the entity identifier of an entity. + * + * @param object $entity + * @param mixed $id + * @todo Rename to assignIdentifier() + */ + public function setIdentifierValues($entity, array $id) + { + foreach ($id as $idField => $idValue) { + $this->reflFields[$idField]->setValue($entity, $idValue); + } + } + + /** + * Sets the specified field to the specified value on the given entity. + * + * @param object $entity + * @param string $field + * @param mixed $value + */ + public function setFieldValue($entity, $field, $value) + { + $this->reflFields[$field]->setValue($entity, $value); + } + + /** + * Gets the specified field's value off the given entity. + * + * @param object $entity + * @param string $field + */ + public function getFieldValue($entity, $field) + { + return $this->reflFields[$field]->getValue($entity); + } + + /** + * Creates a string representation of this instance. + * + * @return string The string representation of this instance. + * @todo Construct meaningful string representation. + */ + public function __toString() + { + return __CLASS__ . '@' . spl_object_hash($this); + } + + /** + * Determines which fields get serialized. + * + * It is only serialized what is necessary for best unserialization performance. + * That means any metadata properties that are not set or empty or simply have + * their default value are NOT serialized. + * + * Parts that are also NOT serialized because they can not be properly unserialized: + * - reflClass (ReflectionClass) + * - reflFields (ReflectionProperty array) + * + * @return array The names of all the fields that should be serialized. + */ + public function __sleep() + { + // This metadata is always serialized/cached. + $serialized = array( + 'associationMappings', + 'columnNames', //TODO: Not really needed. Can use fieldMappings[$fieldName]['columnName'] + 'fieldMappings', + 'fieldNames', + 'identifier', + 'isIdentifierComposite', // TODO: REMOVE + 'name', + 'namespace', // TODO: REMOVE + 'table', + 'rootEntityName', + 'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime. + ); + + // The rest of the metadata is only serialized if necessary. + if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) { + $serialized[] = 'changeTrackingPolicy'; + } + + if ($this->customRepositoryClassName) { + $serialized[] = 'customRepositoryClassName'; + } + + if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE) { + $serialized[] = 'inheritanceType'; + $serialized[] = 'discriminatorColumn'; + $serialized[] = 'discriminatorValue'; + $serialized[] = 'discriminatorMap'; + $serialized[] = 'parentClasses'; + $serialized[] = 'subClasses'; + } + + if ($this->generatorType != self::GENERATOR_TYPE_NONE) { + $serialized[] = 'generatorType'; + if ($this->generatorType == self::GENERATOR_TYPE_SEQUENCE) { + $serialized[] = 'sequenceGeneratorDefinition'; + } + } + + if ($this->isMappedSuperclass) { + $serialized[] = 'isMappedSuperclass'; + } + + if ($this->containsForeignIdentifier) { + $serialized[] = 'containsForeignIdentifier'; + } + + if ($this->isVersioned) { + $serialized[] = 'isVersioned'; + $serialized[] = 'versionField'; + } + + if ($this->lifecycleCallbacks) { + $serialized[] = 'lifecycleCallbacks'; + } + + if ($this->namedQueries) { + $serialized[] = 'namedQueries'; + } + + if ($this->isReadOnly) { + $serialized[] = 'isReadOnly'; + } + + return $serialized; + } + + /** + * Creates a new instance of the mapped class, without invoking the constructor. + * + * @return object + */ + public function newInstance() + { + if ($this->_prototype === null) { + $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name)); + } + + return clone $this->_prototype; + } /** * Restores some state that can not be serialized/unserialized. * @@ -530,11 +758,70 @@ class ClassMetadataInfo } } + /** + * Initializes a new ClassMetadata instance that will hold the object-relational mapping + * metadata of the class with the given name. + * + * @param string $entityName The name of the entity class the new instance is used for. + */ public function initializeReflection($reflService) { + $this->reflClass = $reflService->getClass($this->name); + $this->namespace = $reflService->getClassNamespace($this->name); + $this->table['name'] = $reflService->getClassShortName($this->name); + if ($this->reflClass) { + $this->name = $this->rootEntityName = $this->reflClass->getName(); + } } + /** + * Validate Identifier + * + * @return void + */ + public function validateIdentifier() + { + // Verify & complete identifier mapping + if ( ! $this->identifier && ! $this->isMappedSuperclass) { + throw MappingException::identifierRequired($this->name); + } + + if ($this->usesIdGenerator() && $this->isIdentifierComposite) { + throw MappingException::compositeKeyAssignedIdGeneratorRequired($this->name); + } + } + + /** + * Validate association targets actually exist. + * + * @return void + */ + public function validateAssocations() + { + foreach ($this->associationMappings as $field => $mapping) { + if ( ! \Doctrine\Common\ClassLoader::classExists($mapping['targetEntity']) ) { + throw MappingException::invalidTargetEntityClass($mapping['targetEntity'], $this->name, $mapping['fieldName']); + } + } + } + + /** + * Validate lifecycle callbacks + * + * @param ReflectionService $reflService + * @return void + */ + public function validateLifecycleCallbacks($reflService) + { + foreach ($this->lifecycleCallbacks as $event => $callbacks) { + foreach ($callbacks as $callbackFuncName) { + if ( ! $reflService->hasPublicMethod($this->name, $callbackFuncName)) { + throw MappingException::lifecycleCallbackMethodNotFound($this->name, $callbackFuncName); + } + } + } + } /** * Gets the ReflectionClass instance of the mapped class. @@ -543,9 +830,6 @@ class ClassMetadataInfo */ public function getReflectionClass() { - if ( ! $this->reflClass) { - $this->reflClass = new ReflectionClass($this->name); - } return $this->reflClass; } diff --git a/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php b/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php index c9534a76e..2603c22f9 100644 --- a/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php @@ -38,39 +38,6 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo; */ class DisconnectedClassMetadataFactory extends ClassMetadataFactory { - /** - * @override - */ - protected function newClassMetadataInstance($className) - { - $metadata = new ClassMetadataInfo($className); - if (strpos($className, "\\") !== false) { - $metadata->namespace = strrev(substr( strrev($className), strpos(strrev($className), "\\")+1 )); - } else { - $metadata->namespace = ""; - } - return $metadata; - } - - /** - * Validate runtime metadata is correctly defined. - * - * @param ClassMetadata $class - * @param ClassMetadata $parent - */ - protected function validateRuntimeMetadata($class, $parent) - { - // validate nothing - } - - /** - * @override - */ - protected function getParentClasses($name) - { - return array(); - } - public function getReflectionService() { return new \Doctrine\Common\Persistence\Mapping\StaticReflectionService; diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php index 25b63a8dc..0b5378040 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php @@ -61,4 +61,4 @@ class DDC168Test extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyEmployee', $theEmployee); $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyEmployee', $theEmployee->getSpouse()); } -} \ No newline at end of file +} diff --git a/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php index dae4cd27a..4d7715ebb 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php @@ -15,6 +15,7 @@ class AnnotationDriverTest extends AbstractMappingDriverTest public function testLoadMetadataForNonEntityThrowsException() { $cm = new ClassMetadata('stdClass'); + $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); $reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache()); $annotationDriver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader); @@ -28,6 +29,7 @@ class AnnotationDriverTest extends AbstractMappingDriverTest public function testColumnWithMissingTypeDefaultsToString() { $cm = new ClassMetadata('Doctrine\Tests\ORM\Mapping\ColumnWithoutType'); + $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); $annotationDriver = $this->_loadDriver(); $annotationDriver->loadMetadataForClass('Doctrine\Tests\ORM\Mapping\InvalidColumn', $cm); diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index f663522a6..d100f6f5c 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -532,10 +532,10 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase { $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'); $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); - + $cm->addLifecycleCallback('notfound', 'postLoad'); $this->setExpectedException("Doctrine\ORM\Mapping\MappingException", "Entity 'Doctrine\Tests\Models\CMS\CmsUser' has no method 'notfound' to be registered as lifecycle callback."); - $cm->addLifecycleCallback('notfound', 'postLoad'); + $cm->validateLifecycleCallbacks(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); } /** @@ -545,9 +545,9 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase { $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'); $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); - + $cm->mapManyToOne(array('fieldName' => 'address', 'targetEntity' => 'UnknownClass')); $this->setExpectedException("Doctrine\ORM\Mapping\MappingException", "The target-entity Doctrine\Tests\Models\CMS\UnknownClass cannot be found in 'Doctrine\Tests\Models\CMS\CmsUser#address'."); - $cm->mapManyToOne(array('fieldName' => 'address', 'targetEntity' => 'UnknownClass')); + $cm->validateAssocations(); } } diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php index faf20afb1..4b02a94d1 100644 --- a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php @@ -167,6 +167,8 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase $book = $this->newInstance($metadata); $cm = new \Doctrine\ORM\Mapping\ClassMetadata($metadata->name); + $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); + $driver = $this->createAnnotationDriver(); $driver->loadMetadataForClass($cm->name, $cm); @@ -189,6 +191,8 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase $book = $this->newInstance($metadata); $cm = new \Doctrine\ORM\Mapping\ClassMetadata($metadata->name); + $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService); + $driver->loadMetadataForClass($cm->name, $cm); $this->assertEquals($cm->columnNames, $metadata->columnNames); @@ -249,4 +253,4 @@ class } class EntityGeneratorAuthor {} -class EntityGeneratorComment {} \ No newline at end of file +class EntityGeneratorComment {}