Skip to content

Commit

Permalink
Fix DDC-671 - The sourceEntity field has to be corrected to the subcl…
Browse files Browse the repository at this point in the history
…ass name when copied from a mapped superclass. Otherwise DQL queries will be wrong, generating wrong table aliases.
  • Loading branch information
beberlei committed Sep 21, 2010
1 parent 72f65c3 commit 7dc8ef1
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 53 deletions.
4 changes: 4 additions & 0 deletions lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@ private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $pare
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;
Expand Down
47 changes: 46 additions & 1 deletion tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -458,4 +458,49 @@ public static function loadMetadata(ClassMetadataInfo $metadata)
'initialValue' => 1,
));
}
}
}

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";

}
28 changes: 28 additions & 0 deletions tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,34 @@ protected function _ensureIsLoaded($entityClassName)
{
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()
);
}
}

/**
Expand Down
66 changes: 14 additions & 52 deletions tests/Doctrine/Tests/ORM/Mapping/YamlMappingDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,20 @@ protected function _loadDriver()
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)";
Expand All @@ -34,55 +41,10 @@ public function testJoinTablesWithMappedSuperclassForYamlDriver()
->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;
}

0 comments on commit 7dc8ef1

Please sign in to comment.