Merge pull request #97 from asm89/DDC-1301
[DDC-1301] Fixed count() for fetch="EXTRA_LAZY" on OneToMany association
This commit is contained in:
commit
5c47c07794
@ -124,24 +124,26 @@ class OneToManyPersister extends AbstractCollectionPersister
|
||||
public function count(PersistentCollection $coll)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
$class = $this->_em->getClassMetadata($mapping['targetEntity']);
|
||||
$targetClass = $this->_em->getClassMetadata($mapping['targetEntity']);
|
||||
$sourceClass = $this->_em->getClassMetadata($mapping['sourceEntity']);
|
||||
|
||||
$params = array();
|
||||
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner());
|
||||
|
||||
$where = '';
|
||||
foreach ($class->associationMappings[$mapping['mappedBy']]['joinColumns'] AS $joinColumn) {
|
||||
foreach ($targetClass->associationMappings[$mapping['mappedBy']]['joinColumns'] AS $joinColumn) {
|
||||
if ($where != '') {
|
||||
$where .= ' AND ';
|
||||
}
|
||||
$where .= $joinColumn['name'] . " = ?";
|
||||
if ($class->containsForeignIdentifier) {
|
||||
$params[] = $id[$class->getFieldForColumn($joinColumn['referencedColumnName'])];
|
||||
if ($targetClass->containsForeignIdentifier) {
|
||||
$params[] = $id[$sourceClass->getFieldForColumn($joinColumn['referencedColumnName'])];
|
||||
} else {
|
||||
$params[] = $id[$class->fieldNames[$joinColumn['referencedColumnName']]];
|
||||
$params[] = $id[$sourceClass->fieldNames[$joinColumn['referencedColumnName']]];
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "SELECT count(*) FROM " . $class->getQuotedTableName($this->_conn->getDatabasePlatform()) . " WHERE " . $where;
|
||||
$sql = "SELECT count(*) FROM " . $targetClass->getQuotedTableName($this->_conn->getDatabasePlatform()) . " WHERE " . $where;
|
||||
return $this->_conn->fetchColumn($sql, $params);
|
||||
}
|
||||
|
||||
@ -180,4 +182,4 @@ class OneToManyPersister extends AbstractCollectionPersister
|
||||
return $uow->getEntityPersister($mapping['targetEntity'])
|
||||
->exists($element, array($mapping['mappedBy'] => $id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
33
tests/Doctrine/Tests/Models/Legacy/LegacyArticle.php
Normal file
33
tests/Doctrine/Tests/Models/Legacy/LegacyArticle.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\Legacy;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="legacy_articles")
|
||||
*/
|
||||
class LegacyArticle
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(name="iArticleId", type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $_id;
|
||||
/**
|
||||
* @Column(name="sTopic", type="string", length=255)
|
||||
*/
|
||||
public $_topic;
|
||||
/**
|
||||
* @Column(name="sText", type="text")
|
||||
*/
|
||||
public $_text;
|
||||
/**
|
||||
* @ManyToOne(targetEntity="LegacyUser", inversedBy="_articles")
|
||||
* @JoinColumn(name="iUserId", referencedColumnName="iUserId")
|
||||
*/
|
||||
public $_user;
|
||||
public function setAuthor(LegacyUser $author) {
|
||||
$this->_user = $author;
|
||||
}
|
||||
}
|
41
tests/Doctrine/Tests/Models/Legacy/LegacyCar.php
Normal file
41
tests/Doctrine/Tests/Models/Legacy/LegacyCar.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\Legacy;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="legacy_cars")
|
||||
*/
|
||||
class LegacyCar
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
* @Column(name="iCarId", type="integer", nullable=false)
|
||||
*/
|
||||
public $_id;
|
||||
/**
|
||||
* @ManyToMany(targetEntity="LegacyUser", mappedBy="_cars")
|
||||
*/
|
||||
public $_users;
|
||||
|
||||
/**
|
||||
* @Column(name="sDescription", type="string", length=255, unique=true)
|
||||
*/
|
||||
public $_description;
|
||||
|
||||
function getDescription()
|
||||
{
|
||||
return $this->_description;
|
||||
}
|
||||
|
||||
public function addUser(LegacyUser $user) {
|
||||
$this->_users[] = $user;
|
||||
}
|
||||
|
||||
public function getUsers() {
|
||||
return $this->_users;
|
||||
}
|
||||
}
|
80
tests/Doctrine/Tests/Models/Legacy/LegacyUser.php
Normal file
80
tests/Doctrine/Tests/Models/Legacy/LegacyUser.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\Legacy;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="legacy_users")
|
||||
*/
|
||||
class LegacyUser
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
* @Column(name="iUserId", type="integer", nullable=false)
|
||||
*/
|
||||
public $_id;
|
||||
/**
|
||||
* @Column(name="sUsername", type="string", length=255, unique=true)
|
||||
*/
|
||||
public $_username;
|
||||
/**
|
||||
* @Column(type="string", length=255)
|
||||
*/
|
||||
public $_name;
|
||||
/**
|
||||
* @OneToMany(targetEntity="LegacyArticle", mappedBy="_user")
|
||||
*/
|
||||
public $_articles;
|
||||
/**
|
||||
* @OneToMany(targetEntity="LegacyUserReference", mappedBy="_source", cascade={"remove"})
|
||||
*/
|
||||
public $_references;
|
||||
/**
|
||||
* @ManyToMany(targetEntity="LegacyCar", inversedBy="_users", cascade={"persist", "merge"})
|
||||
* @JoinTable(name="legace_users_cars",
|
||||
* joinColumns={@JoinColumn(name="iUserId", referencedColumnName="iUserId")},
|
||||
* inverseJoinColumns={@JoinColumn(name="iCarId", referencedColumnName="iCarId")}
|
||||
* )
|
||||
*/
|
||||
public $_cars;
|
||||
public function __construct() {
|
||||
$this->_articles = new ArrayCollection;
|
||||
$this->_references = new ArrayCollection;
|
||||
$this->_cars = new ArrayCollection;
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
public function getUsername() {
|
||||
return $this->_username;
|
||||
}
|
||||
|
||||
public function addArticle(LegacyArticle $article) {
|
||||
$this->_articles[] = $article;
|
||||
$article->setAuthor($this);
|
||||
}
|
||||
|
||||
public function addReference($reference)
|
||||
{
|
||||
$this->_references[] = $reference;
|
||||
}
|
||||
|
||||
public function references()
|
||||
{
|
||||
return $this->_references;
|
||||
}
|
||||
|
||||
public function addCar(LegacyCar $car) {
|
||||
$this->_cars[] = $car;
|
||||
$car->addUser($this);
|
||||
}
|
||||
|
||||
public function getCars() {
|
||||
return $this->_cars;
|
||||
}
|
||||
}
|
65
tests/Doctrine/Tests/Models/Legacy/LegacyUserReference.php
Normal file
65
tests/Doctrine/Tests/Models/Legacy/LegacyUserReference.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\Legacy;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="legacy_users_reference")
|
||||
*/
|
||||
class LegacyUserReference
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="LegacyUser", inversedBy="_references")
|
||||
* @JoinColumn(name="iUserIdSource", referencedColumnName="iUserId")
|
||||
*/
|
||||
private $_source;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="LegacyUser", inversedBy="_references")
|
||||
* @JoinColumn(name="iUserIdTarget", referencedColumnName="iUserId")
|
||||
*/
|
||||
private $_target;
|
||||
|
||||
/**
|
||||
* @column(type="string")
|
||||
*/
|
||||
private $_description;
|
||||
|
||||
/**
|
||||
* @column(type="datetime")
|
||||
*/
|
||||
private $_created;
|
||||
|
||||
public function __construct($source, $target, $description)
|
||||
{
|
||||
$source->addReference($this);
|
||||
$target->addReference($this);
|
||||
|
||||
$this->_source = $source;
|
||||
$this->_target = $target;
|
||||
$this->_description = $description;
|
||||
$this->_created = new \DateTime("now");
|
||||
}
|
||||
|
||||
public function source()
|
||||
{
|
||||
return $this->_source;
|
||||
}
|
||||
|
||||
public function target()
|
||||
{
|
||||
return $this->_target;
|
||||
}
|
||||
|
||||
public function setDescription($desc)
|
||||
{
|
||||
$this->_description = $desc;
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->_description;
|
||||
}
|
||||
}
|
148
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1301Test.php
Normal file
148
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1301Test.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @author asm89
|
||||
*/
|
||||
class DDC1301Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
private $userId;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->useModelSet('legacy');
|
||||
parent::setUp();
|
||||
|
||||
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\Legacy\LegacyUser');
|
||||
$class->associationMappings['_articles']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
|
||||
$class->associationMappings['_references']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
|
||||
$class->associationMappings['_cars']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
|
||||
|
||||
$this->loadFixture();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\Legacy\LegacyUser');
|
||||
$class->associationMappings['_articles']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
|
||||
$class->associationMappings['_references']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
|
||||
$class->associationMappings['_cars']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
|
||||
}
|
||||
|
||||
public function testCountNotInitializesLegacyCollection()
|
||||
{
|
||||
$user = $this->_em->find('Doctrine\Tests\Models\Legacy\LegacyUser', $this->userId);
|
||||
$queryCount = $this->getCurrentQueryCount();
|
||||
|
||||
$this->assertFalse($user->_articles->isInitialized());
|
||||
$this->assertEquals(2, count($user->_articles));
|
||||
$this->assertFalse($user->_articles->isInitialized());
|
||||
|
||||
foreach ($user->_articles AS $article) { }
|
||||
|
||||
$this->assertEquals($queryCount + 2, $this->getCurrentQueryCount(), "Expecting two queries to be fired for count, then iteration.");
|
||||
}
|
||||
|
||||
public function testCountNotInitializesLegacyCollectionWithForeignIdentifier()
|
||||
{
|
||||
$user = $this->_em->find('Doctrine\Tests\Models\Legacy\LegacyUser', $this->userId);
|
||||
$queryCount = $this->getCurrentQueryCount();
|
||||
|
||||
$this->assertFalse($user->_references->isInitialized());
|
||||
$this->assertEquals(2, count($user->_references));
|
||||
$this->assertFalse($user->_references->isInitialized());
|
||||
|
||||
foreach ($user->_references AS $reference) { }
|
||||
|
||||
$this->assertEquals($queryCount + 2, $this->getCurrentQueryCount(), "Expecting two queries to be fired for count, then iteration.");
|
||||
}
|
||||
|
||||
public function testCountNotInitializesLegacyManyToManyCollection()
|
||||
{
|
||||
$user = $this->_em->find('Doctrine\Tests\Models\Legacy\LegacyUser', $this->userId);
|
||||
$queryCount = $this->getCurrentQueryCount();
|
||||
|
||||
$this->assertFalse($user->_cars->isInitialized());
|
||||
$this->assertEquals(3, count($user->_cars));
|
||||
$this->assertFalse($user->_cars->isInitialized());
|
||||
|
||||
foreach ($user->_cars AS $reference) { }
|
||||
|
||||
$this->assertEquals($queryCount + 2, $this->getCurrentQueryCount(), "Expecting two queries to be fired for count, then iteration.");
|
||||
}
|
||||
|
||||
public function loadFixture()
|
||||
{
|
||||
$user1 = new \Doctrine\Tests\Models\Legacy\LegacyUser();
|
||||
$user1->_username = "beberlei";
|
||||
$user1->_name = "Benjamin";
|
||||
$user1->_status = "active";
|
||||
|
||||
$user2 = new \Doctrine\Tests\Models\Legacy\LegacyUser();
|
||||
$user2->_username = "jwage";
|
||||
$user2->_name = "Jonathan";
|
||||
$user2->_status = "active";
|
||||
|
||||
$user3 = new \Doctrine\Tests\Models\Legacy\LegacyUser();
|
||||
$user3->_username = "romanb";
|
||||
$user3->_name = "Roman";
|
||||
$user3->_status = "active";
|
||||
|
||||
$this->_em->persist($user1);
|
||||
$this->_em->persist($user2);
|
||||
$this->_em->persist($user3);
|
||||
|
||||
$article1 = new \Doctrine\Tests\Models\Legacy\LegacyArticle();
|
||||
$article1->_topic = "Test";
|
||||
$article1->_text = "Test";
|
||||
$article1->setAuthor($user1);
|
||||
|
||||
$article2 = new \Doctrine\Tests\Models\Legacy\LegacyArticle();
|
||||
$article2->_topic = "Test";
|
||||
$article2->_text = "Test";
|
||||
$article2->setAuthor($user1);
|
||||
|
||||
$this->_em->persist($article1);
|
||||
$this->_em->persist($article2);
|
||||
|
||||
$car1 = new \Doctrine\Tests\Models\Legacy\LegacyCar();
|
||||
$car1->_description = "Test1";
|
||||
|
||||
$car2 = new \Doctrine\Tests\Models\Legacy\LegacyCar();
|
||||
$car2->_description = "Test2";
|
||||
|
||||
$car3 = new \Doctrine\Tests\Models\Legacy\LegacyCar();
|
||||
$car3->_description = "Test3";
|
||||
|
||||
$user1->addCar($car1);
|
||||
$user1->addCar($car2);
|
||||
$user1->addCar($car3);
|
||||
|
||||
$user2->addCar($car1);
|
||||
$user3->addCar($car1);
|
||||
|
||||
$this->_em->persist($car1);
|
||||
$this->_em->persist($car2);
|
||||
$this->_em->persist($car3);
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$detail1 = new \Doctrine\Tests\Models\Legacy\LegacyUserReference($user1, $user2, "foo");
|
||||
$detail2 = new \Doctrine\Tests\Models\Legacy\LegacyUserReference($user1, $user3, "bar");
|
||||
|
||||
$this->_em->persist($detail1);
|
||||
$this->_em->persist($detail2);
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->userId = $user1->getId();
|
||||
}
|
||||
}
|
@ -105,6 +105,12 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
'Doctrine\Tests\Models\StockExchange\Stock',
|
||||
'Doctrine\Tests\Models\StockExchange\Market',
|
||||
),
|
||||
'legacy' => array(
|
||||
'Doctrine\Tests\Models\Legacy\LegacyUser',
|
||||
'Doctrine\Tests\Models\Legacy\LegacyUserReference',
|
||||
'Doctrine\Tests\Models\Legacy\LegacyArticle',
|
||||
'Doctrine\Tests\Models\Legacy\LegacyCar',
|
||||
),
|
||||
);
|
||||
|
||||
protected function useModelSet($setName)
|
||||
@ -204,6 +210,12 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
$conn->executeUpdate('DELETE FROM exchange_stocks');
|
||||
$conn->executeUpdate('DELETE FROM exchange_markets');
|
||||
}
|
||||
if (isset($this->_usedModelSets['legacy'])) {
|
||||
$conn->executeUpdate('DELETE FROM legacy_articles');
|
||||
$conn->executeUpdate('DELETE FROM legacy_cars');
|
||||
$conn->executeUpdate('DELETE FROM legacy_users');
|
||||
$conn->executeUpdate('DELETE FROM legacy_users_reference');
|
||||
}
|
||||
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user