bug #17990 [DoctrineBridge][Form] Fix performance regression in EntityType (kimlai)

This PR was submitted for the master branch but it was merged into the 2.7 branch instead (closes #17990).

Discussion
----------

[DoctrineBridge][Form] Fix performance regression in EntityType

| Q             | A
| ------------- | ---
| Branch        | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

A performance regression was introduced in 2336d5c466

Before, the default behaviour of the `DoctrineLoader` was to only fetch the entities selected in the submitted form.

After, the optimization was only performed when the `choice_value` option was set to `null`.
However, the `DoctrineType` sets a non-null default value to `choice_value`, which means that the default behaviour was not using the optimization anymore.

This commit restores the default behaviour (while keeping the previous commit intent).

References:
- https://github.com/symfony/symfony/blob/v2.7.10/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php#L149
- https://github.com/symfony/symfony/blob/v2.7.10/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php#L216

Commits
-------

64c80a6 [DoctrineBridge][Form] Fix performance regression in EntityType
This commit is contained in:
Fabien Potencier 2016-03-03 13:52:48 +01:00
commit 46d1d2407a
2 changed files with 27 additions and 1 deletions

View File

@ -146,7 +146,9 @@ class DoctrineChoiceLoader implements ChoiceLoaderInterface
// Optimize performance in case we have an object loader and
// a single-field identifier
if (null === $value && !$this->choiceList && $this->objectLoader && $this->idReader->isSingleId()) {
$optimize = null === $value || is_array($value) && $value[0] === $this->idReader;
if ($optimize && !$this->choiceList && $this->objectLoader && $this->idReader->isSingleId()) {
$unorderedObjects = $this->objectLoader->getEntitiesByIds($this->idReader->getIdField(), $values);
$objectsById = array();
$objects = array();

View File

@ -789,6 +789,30 @@ class EntityTypeTest extends TypeTestCase
$this->assertSame('BooGroup/Bar', $field->getViewData());
}
public function testChoicesForValuesOptimization()
{
$entity1 = new SingleIntIdEntity(1, 'Foo');
$entity2 = new SingleIntIdEntity(2, 'Bar');
$this->persist(array($entity1, $entity2));
$field = $this->factory->createNamed('name', 'Symfony\Bridge\Doctrine\Form\Type\EntityType', null, array(
'em' => 'default',
'class' => self::SINGLE_IDENT_CLASS,
'choice_label' => 'name',
));
$this->em->clear();
$field->submit(1);
$unitOfWorkIdentityMap = $this->em->getUnitOfWork()->getIdentityMap();
$managedEntitiesNames = array_map('strval', $unitOfWorkIdentityMap['Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity']);
$this->assertContains((string) $entity1, $managedEntitiesNames);
$this->assertNotContains((string) $entity2, $managedEntitiesNames);
}
public function testGroupByChoices()
{
$item1 = new GroupableEntity(1, 'Foo', 'Group1');