From 7dc8ef1db9b55ab1a76f416d78e6bd882bbbd1d5 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 21 Sep 2010 23:14:45 +0200 Subject: [PATCH] Fix DDC-671 - The sourceEntity field has to be corrected to the subclass name when copied from a mapped superclass. Otherwise DQL queries will be wrong, generating wrong table aliases. --- .../ORM/Mapping/ClassMetadataFactory.php | 4 ++ .../ORM/Mapping/AbstractMappingDriverTest.php | 47 ++++++++++++- .../ORM/Mapping/AnnotationDriverTest.php | 28 ++++++++ .../ORM/Mapping/YamlMappingDriverTest.php | 66 ++++--------------- 4 files changed, 92 insertions(+), 53 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 63c869b38..51994f334 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -379,6 +379,10 @@ class ClassMetadataFactory private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass) { foreach ($parentClass->associationMappings as $field => $mapping) { + if ($parentClass->isMappedSuperclass) { + $mapping['sourceEntity'] = $subClass->name; + } + //$subclassMapping = $mapping; if ( ! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) { $mapping['inherited'] = $parentClass->name; diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 653cff7d7..ad1fa3d5c 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -458,4 +458,49 @@ class User 'initialValue' => 1, )); } -} \ No newline at end of file +} + +abstract class AbstractContentItem +{ + + /** + * Doctrine2 entity id + * @var integer + */ + private $id; + /** + * The parent directory + * @var Directory + */ + protected $parentDirectory; + /** + * Filename (without extension) or directory name + * @var string + */ + protected $name; +} + +class Directory extends AbstractContentItem +{ + + protected $subDirectories; + /** + * This is a collection of files that are contained in this Directory. Files, for example, could be Pages, but even other files + * like media files (css, images etc) are possible. + * + * @var \Doctrine\Common\Collections\Collection + * @access protected + */ + protected $containedFiles; + /** + * @var string + */ + protected $url; +} + +class Page extends AbstractContentItem +{ + + protected $extension = "html"; + +} diff --git a/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php index 468ef680d..f28f7a6d4 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php @@ -109,6 +109,34 @@ class AnnotationDriverTest extends AbstractMappingDriverTest { new $entityClassName; } + + /** + * @group DDC-671 + * + * Entities for this test are in AbstractMappingDriverTest + */ + public function testJoinTablesWithMappedSuperclassForAnnotationDriver() + { + $em = $this->_getTestEntityManager(); + $em->getConfiguration()->setMetadataDriverImpl($this->_loadDriver()); + + $classPage = $em->getClassMetadata('Doctrine\Tests\ORM\Mapping\Page'); + $this->assertEquals('Doctrine\Tests\ORM\Mapping\Page', $classPage->associationMappings['parentDirectory']['sourceEntity']); + $classDirectory = $em->getClassMetadata('Doctrine\Tests\ORM\Mapping\Directory'); + $this->assertEquals('Doctrine\Tests\ORM\Mapping\Directory', $classDirectory->associationMappings['parentDirectory']['sourceEntity']); + + $dql = "SELECT f FROM Doctrine\Tests\ORM\Mapping\Page f JOIN f.parentDirectory d " . + "WHERE (d.url = :url) AND (f.extension = :extension)"; + + $query = $em->createQuery($dql) + ->setParameter('url', "test") + ->setParameter('extension', "extension"); + + $this->assertEquals( + 'SELECT c0_.id AS id0, c0_.extension AS extension1, c0_.parent_directory_id AS parent_directory_id2 FROM core_content_pages c0_ INNER JOIN core_content_directories c1_ ON c0_.parent_directory_id = c1_.id WHERE (c1_.url = ?) AND (c0_.extension = ?)', + $query->getSql() + ); + } } /** diff --git a/tests/Doctrine/Tests/ORM/Mapping/YamlMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/YamlMappingDriverTest.php index aa7ce716b..46e3ff15b 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/YamlMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/YamlMappingDriverTest.php @@ -19,13 +19,20 @@ class YamlMappingDriverTest extends AbstractMappingDriverTest return new YamlDriver(__DIR__ . DIRECTORY_SEPARATOR . 'yaml'); } + /** + * @group DDC-671 + * + * Entities for this test are in AbstractMappingDriverTest + */ public function testJoinTablesWithMappedSuperclassForYamlDriver() { $em = $this->_getTestEntityManager(); - $em->getConfiguration()->setMetadataDriverImpl(new \Doctrine\ORM\Mapping\Driver\YamlDriver(__DIR__ . '/yaml/')); + $em->getConfiguration()->setMetadataDriverImpl($this->_loadDriver()); - var_dump($em->getClassMetadata('Doctrine\Tests\ORM\Mapping\Page')); - var_dump($em->getClassMetadata('Doctrine\Tests\ORM\Mapping\Directory')); + $classPage = $em->getClassMetadata('Doctrine\Tests\ORM\Mapping\Page'); + $this->assertEquals('Doctrine\Tests\ORM\Mapping\Page', $classPage->associationMappings['parentDirectory']['sourceEntity']); + $classDirectory = $em->getClassMetadata('Doctrine\Tests\ORM\Mapping\Directory'); + $this->assertEquals('Doctrine\Tests\ORM\Mapping\Directory', $classDirectory->associationMappings['parentDirectory']['sourceEntity']); $dql = "SELECT f FROM Doctrine\Tests\ORM\Mapping\Page f JOIN f.parentDirectory d " . "WHERE (d.url = :url) AND (f.extension = :extension)"; @@ -34,55 +41,10 @@ class YamlMappingDriverTest extends AbstractMappingDriverTest ->setParameter('url', "test") ->setParameter('extension', "extension"); - var_dump($query->getSql()); - - // Is there a way to generalize this more? (Instead of a2_., check if the table prefix in the ON clause is set within a FROM or JOIN clause..) - $this->assertTrue(strpos($query->getSql(), 'a2_.') === false); + $this->assertEquals( + 'SELECT c0_.id AS id0, c0_.extension AS extension1, c0_.parent_directory_id AS parent_directory_id2 FROM core_content_pages c0_ INNER JOIN core_content_directories c1_ ON c0_.parent_directory_id = c1_.id WHERE (c1_.url = ?) AND (c0_.extension = ?)', + $query->getSql() + ); } } - -class Directory extends AbstractContentItem -{ - - protected $subDirectories; - /** - * This is a collection of files that are contained in this Directory. Files, for example, could be Pages, but even other files - * like media files (css, images etc) are possible. - * - * @var \Doctrine\Common\Collections\Collection - * @access protected - */ - protected $containedFiles; - /** - * @var string - */ - protected $url; -} - -class Page extends AbstractContentItem -{ - - protected $extension = "html"; - -} - -abstract class AbstractContentItem -{ - - /** - * Doctrine2 entity id - * @var integer - */ - private $id; - /** - * The parent directory - * @var Directory - */ - protected $parentDirectory; - /** - * Filename (without extension) or directory name - * @var string - */ - protected $name; -}