From 92476b5953185b640ee6d4959f9568912c271305 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sat, 16 Jul 2016 12:12:33 +0200 Subject: [PATCH] #5934 - add `fetch` option to `AssociationOverride` in order to override fetch strategy for subclasses of entities --- docs/en/reference/inheritance-mapping.rst | 1 + doctrine-mapping.xsd | 1 + .../ORM/Mapping/AssociationOverride.php | 9 ++++ .../ORM/Mapping/ClassMetadataInfo.php | 4 ++ .../ORM/Mapping/Driver/AnnotationDriver.php | 5 ++ lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 5 ++ .../ORM/Mapping/Driver/YamlDriver.php | 5 ++ .../Models/DDC5934/DDC5934BaseContract.php | 53 +++++++++++++++++++ .../Tests/Models/DDC5934/DDC5934Contract.php | 24 +++++++++ .../Tests/Models/DDC5934/DDC5934Member.php | 24 +++++++++ .../ORM/Mapping/AbstractMappingDriverTest.php | 13 +++++ ...sts.Models.DDC5934.DDC5934BaseContract.php | 17 ++++++ ...e.Tests.Models.DDC5934.DDC5934Contract.php | 7 +++ ...Models.DDC5934.DDC5934BaseContract.dcm.xml | 15 ++++++ ...sts.Models.DDC5934.DDC5934Contract.dcm.xml | 13 +++++ ...Models.DDC5934.DDC5934BaseContract.dcm.yml | 12 +++++ ...sts.Models.DDC5934.DDC5934Contract.dcm.yml | 5 ++ 17 files changed, 213 insertions(+) create mode 100644 tests/Doctrine/Tests/Models/DDC5934/DDC5934BaseContract.php create mode 100644 tests/Doctrine/Tests/Models/DDC5934/DDC5934Contract.php create mode 100644 tests/Doctrine/Tests/Models/DDC5934/DDC5934Member.php create mode 100644 tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.php create mode 100644 tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934Contract.php create mode 100644 tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.xml create mode 100644 tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.xml create mode 100644 tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.yml create mode 100644 tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.yml diff --git a/docs/en/reference/inheritance-mapping.rst b/docs/en/reference/inheritance-mapping.rst index 9e895fcbc..2063624fe 100644 --- a/docs/en/reference/inheritance-mapping.rst +++ b/docs/en/reference/inheritance-mapping.rst @@ -455,6 +455,7 @@ Things to note: - The association type *CANNOT* be changed. - The override could redefine the joinTables or joinColumns depending on the association type. - The override could redefine inversedBy to reference more than one extended entity. +- The override could redefine fetch to modify the fetch strategy of the extended entity. Attribute Override ~~~~~~~~~~~~~~~~~~~~ diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd index bb8624190..18fb6838a 100644 --- a/doctrine-mapping.xsd +++ b/doctrine-mapping.xsd @@ -567,6 +567,7 @@ + diff --git a/lib/Doctrine/ORM/Mapping/AssociationOverride.php b/lib/Doctrine/ORM/Mapping/AssociationOverride.php index 83cff4179..e208b1622 100644 --- a/lib/Doctrine/ORM/Mapping/AssociationOverride.php +++ b/lib/Doctrine/ORM/Mapping/AssociationOverride.php @@ -57,4 +57,13 @@ final class AssociationOverride implements Annotation * @var string */ public $inversedBy; + + /** + * The fetching strategy to use for the association. + * + * @var string + * + * @Enum({"LAZY", "EAGER", "EXTRA_LAZY"}) + */ + public $fetch; } diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index f265814b1..e3da55bdf 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2153,6 +2153,10 @@ class ClassMetadataInfo implements ClassMetadata $mapping['joinTable'] = $overrideMapping['joinTable']; } + if (isset($overrideMapping['fetch'])) { + $mapping['fetch'] = $overrideMapping['fetch']; + } + $mapping['joinColumnFieldNames'] = null; $mapping['joinTableColumns'] = null; $mapping['sourceToTargetKeyColumns'] = null; diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index b5a5b714c..59730f6b2 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -470,6 +470,11 @@ class AnnotationDriver extends AbstractAnnotationDriver $override['inversedBy'] = $associationOverride->inversedBy; } + // Check for `fetch` + if ($associationOverride->fetch) { + $override['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $associationOverride->fetch); + } + $metadata->setAssociationOverride($fieldName, $override); } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index d7099663f..0d51c4c92 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -621,6 +621,11 @@ class XmlDriver extends FileDriver $override['inversedBy'] = (string) $overrideElement->{'inversed-by'}['name']; } + // Check for `fetch` + if (isset($overrideElement['fetch'])) { + $override['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string) $overrideElement['fetch']); + } + $metadata->setAssociationOverride($fieldName, $override); } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index 5161ed0f0..394722847 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -622,6 +622,11 @@ class YamlDriver extends FileDriver $override['inversedBy'] = (string) $associationOverrideElement['inversedBy']; } + // Check for `fetch` + if (isset($associationOverrideElement['fetch'])) { + $override['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $associationOverrideElement['fetch']); + } + $metadata->setAssociationOverride($fieldName, $override); } } diff --git a/tests/Doctrine/Tests/Models/DDC5934/DDC5934BaseContract.php b/tests/Doctrine/Tests/Models/DDC5934/DDC5934BaseContract.php new file mode 100644 index 000000000..84970c270 --- /dev/null +++ b/tests/Doctrine/Tests/Models/DDC5934/DDC5934BaseContract.php @@ -0,0 +1,53 @@ +members = new ArrayCollection(); + } + + public static function loadMetadata(ClassMetadata $metadata) + { + $metadata->mapField([ + 'id' => true, + 'fieldName' => 'id', + 'type' => 'integer', + 'columnName' => 'id', + ]); + + $metadata->mapManyToMany([ + 'fieldName' => 'members', + 'targetEntity' => 'DDC5934Member', + ]); + + $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); + } +} diff --git a/tests/Doctrine/Tests/Models/DDC5934/DDC5934Contract.php b/tests/Doctrine/Tests/Models/DDC5934/DDC5934Contract.php new file mode 100644 index 000000000..e26c4d665 --- /dev/null +++ b/tests/Doctrine/Tests/Models/DDC5934/DDC5934Contract.php @@ -0,0 +1,24 @@ +setAssociationOverride('members', [ + 'fetch' => ClassMetadata::FETCH_EXTRA_LAZY, + ]); + } +} diff --git a/tests/Doctrine/Tests/Models/DDC5934/DDC5934Member.php b/tests/Doctrine/Tests/Models/DDC5934/DDC5934Member.php new file mode 100644 index 000000000..ff85d6c66 --- /dev/null +++ b/tests/Doctrine/Tests/Models/DDC5934/DDC5934Member.php @@ -0,0 +1,24 @@ +contracts = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php index 4e19c987c..f857bed45 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php @@ -28,6 +28,7 @@ use Doctrine\Tests\Models\DDC1476\DDC1476EntityWithDefaultFieldType; use Doctrine\Tests\Models\DDC2825\ExplicitSchemaAndTable; use Doctrine\Tests\Models\DDC2825\SchemaAndTableInTableName; use Doctrine\Tests\Models\DDC3579\DDC3579Admin; +use Doctrine\Tests\Models\DDC5934\DDC5934Contract; use Doctrine\Tests\Models\DDC869\DDC869ChequePayment; use Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment; use Doctrine\Tests\Models\DDC869\DDC869PaymentRepository; @@ -816,6 +817,18 @@ abstract class AbstractMappingDriverTest extends OrmTestCase $this->assertEquals('admins', $adminGroups['inversedBy']); } + /** + * @group DDC-5934 + */ + public function testFetchOverrideMapping() + { + // check override metadata + $contractMetadata = $this->createClassMetadataFactory()->getMetadataFor(DDC5934Contract::class); + + $this->assertArrayHasKey('members', $contractMetadata->associationMappings); + $this->assertSame(ClassMetadata::FETCH_EXTRA_LAZY, $contractMetadata->associationMappings['members']['fetch']); + } + /** * @group DDC-964 */ diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.php new file mode 100644 index 000000000..fca4bb118 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.php @@ -0,0 +1,17 @@ +mapField([ + 'id' => true, + 'fieldName' => 'id', + 'type' => 'integer', + 'columnName' => 'id', +]); + +$metadata->mapManyToMany([ + 'fieldName' => 'members', + 'targetEntity' => 'DDC5934Member', +]); + +$metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934Contract.php b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934Contract.php new file mode 100644 index 000000000..3ecf178a6 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934Contract.php @@ -0,0 +1,7 @@ +setAssociationOverride('members', [ + 'fetch' => ClassMetadata::FETCH_EXTRA_LAZY, +]); diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.xml new file mode 100644 index 000000000..78a5af6b8 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.xml new file mode 100644 index 000000000..bba41b94e --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.xml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.yml new file mode 100644 index 000000000..2044c9be5 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.yml @@ -0,0 +1,12 @@ +Doctrine\Tests\Models\DDC5934\DDC5934BaseContract: + type: mappedSuperclass + id: + id: + type: integer + column: id + generator: + strategy: AUTO + manyToMany: + members: + targetEntity: DDC5934Member + inversedBy: contract diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.yml b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.yml new file mode 100644 index 000000000..45ba14585 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.yml @@ -0,0 +1,5 @@ +Doctrine\Tests\Models\DDC5934\DDC5934Contract: + type: entity + associationOverride: + members: + fetch: EXTRA_LAZY