diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadata.php b/lib/Doctrine/ORM/Mapping/ClassMetadata.php index 9caa79e11..2c9ec63b7 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadata.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadata.php @@ -122,6 +122,25 @@ class ClassMetadata extends ClassMetadataInfo $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 ( ! class_exists($mapping['targetEntity']) ) { + #throw MappingException::invalidTargetEntityClass($mapping['targetEntity'], $this->name, $mapping['fieldName']); + } + + return $mapping; + } + /** * Extracts the identifier values of an entity of this class. * diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php index 97fbf94f6..a359081c8 100644 --- a/lib/Doctrine/ORM/Mapping/MappingException.php +++ b/lib/Doctrine/ORM/Mapping/MappingException.php @@ -298,4 +298,9 @@ class MappingException extends \Doctrine\ORM\ORMException { return new self("Entity '" . $className . "' has no method '" . $methodName . "' to be registered as lifecycle callback."); } + + public static function invalidTargetEntityClass($targetEntity, $sourceEntity, $associationName) + { + return new self("The target-entity " . $targetEntity . " cannot be found in '" . $sourceEntity."#".$associationName."'."); + } } \ No newline at end of file diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index f53ec67a7..8af2a7337 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -594,8 +594,8 @@ class UnitOfWork implements PropertyChangedListener throw new InvalidArgumentException("A new entity was found through the relationship '" . $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' that was not" . " configured to cascade persist operations for entity: " . self::objToStr($entry) . "." - . " Explicitly persist the new entity or configure cascading persist operations" - . " on the relationship. If you cannot find out which entity causes the problem" + . " Explicitly call EntityManager#persist() on this entity or configure to cascade persist " + . " the association. If you cannot find out which entity causes the problem" . " implement '" . $assoc['targetEntity'] . "#__toString()' to get a clue."); } $this->persistNew($targetClass, $entry); diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 98c43a5b9..05498c1d5 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -551,4 +551,8 @@ class Dog extends Animal { } -} \ No newline at end of file +} + +class Address {} +class Phonenumber {} +class Group {} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php b/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php index 93504ec53..b4ed5b34c 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php @@ -197,6 +197,7 @@ class MappedSuperclassBase { private $mappedRelated1; private $transient; } +class MappedSuperclassRelated1 {} /** @Entity */ class EntitySubClass2 extends MappedSuperclassBase { diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php index dbb82f054..868dac7cd 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php @@ -32,12 +32,12 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase // Add a mapped field $cm1->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true)); // and a mapped association - $cm1->mapOneToOne(array('fieldName' => 'other', 'targetEntity' => 'Other', 'mappedBy' => 'this')); + $cm1->mapOneToOne(array('fieldName' => 'other', 'targetEntity' => 'TestEntity1', 'mappedBy' => 'this')); // and an association on the owning side $joinColumns = array( array('name' => 'other_id', 'referencedColumnName' => 'id') ); - $cm1->mapOneToOne(array('fieldName' => 'association', 'targetEntity' => 'Other', 'joinColumns' => $joinColumns)); + $cm1->mapOneToOne(array('fieldName' => 'association', 'targetEntity' => 'TestEntity1', 'joinColumns' => $joinColumns)); // and an id generator type $cm1->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index fed31d9c5..7a36f808a 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -29,7 +29,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase $cm->setParentClasses(array("UserParent")); $cm->setCustomRepositoryClass("UserRepository"); $cm->setDiscriminatorColumn(array('name' => 'disc', 'type' => 'integer')); - $cm->mapOneToOne(array('fieldName' => 'phonenumbers', 'targetEntity' => 'Bar', 'mappedBy' => 'foo')); + $cm->mapOneToOne(array('fieldName' => 'phonenumbers', 'targetEntity' => 'CmsAddress', 'mappedBy' => 'foo')); $cm->markReadOnly(); $cm->addNamedQuery(array('name' => 'dql', 'query' => 'foo')); $this->assertEquals(1, count($cm->associationMappings)); @@ -52,7 +52,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase $oneOneMapping = $cm->getAssociationMapping('phonenumbers'); $this->assertTrue($oneOneMapping['fetch'] == ClassMetadata::FETCH_LAZY); $this->assertEquals('phonenumbers', $oneOneMapping['fieldName']); - $this->assertEquals('Doctrine\Tests\Models\CMS\Bar', $oneOneMapping['targetEntity']); + $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress', $oneOneMapping['targetEntity']); $this->assertTrue($cm->isReadOnly); $this->assertEquals(array('dql' => 'foo'), $cm->namedQueries); } diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/AbstractClassMetadataExporterTest.php b/tests/Doctrine/Tests/ORM/Tools/Export/AbstractClassMetadataExporterTest.php index c9bfdccf0..8e263ba40 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Export/AbstractClassMetadataExporterTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Export/AbstractClassMetadataExporterTest.php @@ -98,6 +98,8 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest public function testExportDirectoryAndFilesAreCreated() { + $this->_deleteDirectory(__DIR__ . '/export/'.$this->_getType()); + $type = $this->_getType(); $metadataDriver = $this->_createMetadataDriver($type, __DIR__ . '/' . $type); $em = $this->_createEntityManager($metadataDriver); @@ -320,12 +322,6 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest $this->assertEquals('user', $class->associationMappings['address']['inversedBy']); } - public function __destruct() - { - $type = $this->_getType(); - $this->_deleteDirectory(__DIR__ . '/export/'.$this->_getType()); - } - protected function _deleteDirectory($path) { if (is_file($path)) { @@ -338,4 +334,17 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest return rmdir($path); } } +} + +class Address +{ + +} +class Phonenumber +{ + +} +class Group +{ + } \ No newline at end of file