Merge branch 'DDC-2430'
This commit is contained in:
commit
30f90a6f49
14
UPGRADE.md
14
UPGRADE.md
@ -28,6 +28,20 @@ Now parenthesis are considered, the previous DQL will generate:
|
|||||||
|
|
||||||
SELECT 100 / (2 * 2) FROM my_entity
|
SELECT 100 / (2 * 2) FROM my_entity
|
||||||
|
|
||||||
|
## Compatibility Bugfix in PersistentCollection#matching() breaks BC
|
||||||
|
|
||||||
|
In Doctrine 2.3 it was possible to use the new ``matching($criteria)``
|
||||||
|
functionality by adding constraints for assocations based on ID:
|
||||||
|
|
||||||
|
Criteria::expr()->eq('association', $assocation->getId());
|
||||||
|
|
||||||
|
This functionality does not work on InMemory collections however, because
|
||||||
|
in memory criteria compares object values based on reference.
|
||||||
|
As of 2.4 the above code will throw an exception. You need to change
|
||||||
|
offending code to pass the ``$assocation`` reference directly:
|
||||||
|
|
||||||
|
Criteria::expr()->eq('association', $assocation);
|
||||||
|
|
||||||
# Upgrade to 2.3
|
# Upgrade to 2.3
|
||||||
|
|
||||||
## EntityManager#find() not calls EntityRepository#find() anymore
|
## EntityManager#find() not calls EntityRepository#find() anymore
|
||||||
|
@ -850,12 +850,8 @@ final class PersistentCollection implements Collection, Selectable
|
|||||||
throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany associations at the moment.");
|
throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany associations at the moment.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $this->em
|
|
||||||
->getClassMetadata(get_class($this->owner))
|
|
||||||
->getSingleIdReflectionProperty()
|
|
||||||
->getValue($this->owner);
|
|
||||||
$builder = Criteria::expr();
|
$builder = Criteria::expr();
|
||||||
$ownerExpression = $builder->eq($this->backRefFieldName, $id);
|
$ownerExpression = $builder->eq($this->backRefFieldName, $this->owner);
|
||||||
$expression = $criteria->getWhereExpression();
|
$expression = $criteria->getWhereExpression();
|
||||||
$expression = $expression ? $builder->andX($expression, $ownerExpression) : $ownerExpression;
|
$expression = $expression ? $builder->andX($expression, $ownerExpression) : $ownerExpression;
|
||||||
|
|
||||||
|
@ -1583,7 +1583,7 @@ class BasicEntityPersister
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$visitor = new SqlExpressionVisitor($this);
|
$visitor = new SqlExpressionVisitor($this, $this->class);
|
||||||
|
|
||||||
return $visitor->dispatch($expression);
|
return $visitor->dispatch($expression);
|
||||||
}
|
}
|
||||||
|
20
lib/Doctrine/ORM/Persisters/PersisterException.php
Normal file
20
lib/Doctrine/ORM/Persisters/PersisterException.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Doctrine\ORM\Persisters;
|
||||||
|
|
||||||
|
use Doctrine\ORM\ORMException;
|
||||||
|
|
||||||
|
class PersisterException extends ORMException
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return PersisterException
|
||||||
|
*/
|
||||||
|
static public function matchingAssocationFieldRequiresObject($class, $associationName)
|
||||||
|
{
|
||||||
|
return new self(sprintf(
|
||||||
|
"Cannot match on %s::%s with a non-object value. Matching objects by id is " .
|
||||||
|
"not compatible with matching on an in-memory collection, which compares objects by reference.",
|
||||||
|
$class, $associationName
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Persisters;
|
namespace Doctrine\ORM\Persisters;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
|
|
||||||
use Doctrine\Common\Collections\Expr\ExpressionVisitor;
|
use Doctrine\Common\Collections\Expr\ExpressionVisitor;
|
||||||
use Doctrine\Common\Collections\Expr\Comparison;
|
use Doctrine\Common\Collections\Expr\Comparison;
|
||||||
use Doctrine\Common\Collections\Expr\Value;
|
use Doctrine\Common\Collections\Expr\Value;
|
||||||
@ -37,12 +39,18 @@ class SqlExpressionVisitor extends ExpressionVisitor
|
|||||||
*/
|
*/
|
||||||
private $persister;
|
private $persister;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Doctrine\ORM\Mapping\ClassMetadata
|
||||||
|
*/
|
||||||
|
private $classMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \Doctrine\ORM\Persisters\BasicEntityPersister $persister
|
* @param \Doctrine\ORM\Persisters\BasicEntityPersister $persister
|
||||||
*/
|
*/
|
||||||
public function __construct(BasicEntityPersister $persister)
|
public function __construct(BasicEntityPersister $persister, ClassMetadata $classMetadata)
|
||||||
{
|
{
|
||||||
$this->persister = $persister;
|
$this->persister = $persister;
|
||||||
|
$this->classMetadata = $classMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,6 +65,10 @@ class SqlExpressionVisitor extends ExpressionVisitor
|
|||||||
$field = $comparison->getField();
|
$field = $comparison->getField();
|
||||||
$value = $comparison->getValue()->getValue(); // shortcut for walkValue()
|
$value = $comparison->getValue()->getValue(); // shortcut for walkValue()
|
||||||
|
|
||||||
|
if (isset($this->classMetadata->associationMappings[$field]) && ! is_object($value)) {
|
||||||
|
throw PersisterException::matchingAssocationFieldRequiresObject($this->classMetadata->name, $field);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->persister->getSelectConditionStatementSQL($field, $value, null, $comparison->getOperator());
|
return $this->persister->getSelectConditionStatementSQL($field, $value, null, $comparison->getOperator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,7 @@ use Doctrine\Tests\Models\CMS\CmsEmail;
|
|||||||
use Doctrine\Tests\Models\CMS\CmsAddress;
|
use Doctrine\Tests\Models\CMS\CmsAddress;
|
||||||
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
|
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
|
||||||
use Doctrine\Common\Collections\Criteria;
|
use Doctrine\Common\Collections\Criteria;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
require_once __DIR__ . '/../../TestInit.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author robo
|
* @author robo
|
||||||
@ -781,6 +780,29 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
$this->assertEquals(4, count($users));
|
$this->assertEquals(4, count($users));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group DDC-2430
|
||||||
|
*/
|
||||||
|
public function testMatchingCriteriaAssocationByObjectInMemory()
|
||||||
|
{
|
||||||
|
list($userId, $addressId) = $this->loadAssociatedFixture();
|
||||||
|
|
||||||
|
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $userId);
|
||||||
|
|
||||||
|
$criteria = new Criteria(
|
||||||
|
Criteria::expr()->gte('user', $user)
|
||||||
|
);
|
||||||
|
|
||||||
|
$repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsAddress');
|
||||||
|
$addresses = $repository->matching($criteria);
|
||||||
|
|
||||||
|
$this->assertEquals(1, count($addresses));
|
||||||
|
|
||||||
|
$addresses = new ArrayCollection($repository->findAll());
|
||||||
|
|
||||||
|
$this->assertEquals(1, count($addresses->matching($criteria)));
|
||||||
|
}
|
||||||
|
|
||||||
public function testMatchingCriteriaContainsComparison()
|
public function testMatchingCriteriaContainsComparison()
|
||||||
{
|
{
|
||||||
$this->loadFixture();
|
$this->loadFixture();
|
||||||
|
@ -343,17 +343,32 @@ class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
|
|
||||||
$repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyContract");
|
$repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyContract");
|
||||||
$contracts = $repository->matching(new Criteria(
|
$contracts = $repository->matching(new Criteria(
|
||||||
Criteria::expr()->eq('salesPerson', $this->salesPerson->getId())
|
Criteria::expr()->eq('salesPerson', $this->salesPerson)
|
||||||
));
|
));
|
||||||
$this->assertEquals(3, count($contracts));
|
$this->assertEquals(3, count($contracts));
|
||||||
|
|
||||||
$repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyFixContract");
|
$repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyFixContract");
|
||||||
$contracts = $repository->matching(new Criteria(
|
$contracts = $repository->matching(new Criteria(
|
||||||
Criteria::expr()->eq('salesPerson', $this->salesPerson->getId())
|
Criteria::expr()->eq('salesPerson', $this->salesPerson)
|
||||||
));
|
));
|
||||||
$this->assertEquals(1, count($contracts));
|
$this->assertEquals(1, count($contracts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group DDC-2430
|
||||||
|
*/
|
||||||
|
public function testMatchingNonObjectOnAssocationThrowsException()
|
||||||
|
{
|
||||||
|
$this->loadFullFixture();
|
||||||
|
|
||||||
|
$repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyContract");
|
||||||
|
|
||||||
|
$this->setExpectedException('Doctrine\ORM\Persisters\PersisterException', 'annot match on Doctrine\Tests\Models\Company\CompanyContract::salesPerson with a non-object value.');
|
||||||
|
$contracts = $repository->matching(new Criteria(
|
||||||
|
Criteria::expr()->eq('salesPerson', $this->salesPerson->getId())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group DDC-834
|
* @group DDC-834
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user