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