Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storeAs option for references #1349

Merged
merged 20 commits into from
May 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d81f1e9
Add 3 different types to store MongoDB references (simple, partial & …
Jan 22, 2016
11f7a2a
Correct the coding standards (empty line between namespace/import)
Jan 22, 2016
a78ff55
Update the 'storeAs' values as discussed in #1349
Mar 18, 2016
3b4851c
Add the storeAs key to all the drivers and add some todos to redirect…
Mar 18, 2016
c8f2afb
Correct the mapping variable
Apr 6, 2016
60fad18
Synchronize the "simple" and "storeAs" mapping information for backwa…
Apr 6, 2016
003dccf
Introduce a new ReferenceUser test class to test the different storeA…
Apr 6, 2016
c6b20e2
Remove he field references, it breaks Doctrine\ODM\MongoDB\Tests\Sche…
Apr 6, 2016
618b833
Expand the unit tests for the ClassMetadataInfo::mapField "storeAs" c…
Apr 6, 2016
14b921b
Update the DM::createDBRef code to use the "storeAs" value
Apr 6, 2016
f2ceef5
Remove the "simple" reference handling throughout the code and only s…
Apr 15, 2016
2a3f77a
Use a custom type in the XML schema mapping and remove the camel case…
Apr 17, 2016
b0a7256
Check the availability of the 'storeAs' key once
Apr 17, 2016
ed0a32c
Remove the group docblock formatting
May 4, 2016
7e2ee3c
Update the "simple reference" documentation (and call it "storing ref…
May 4, 2016
2c6d6ab
Correct the dbrefs link to the Mongo documentation
May 4, 2016
4e1a748
Add an extra backwards compatibility note for storing references
May 4, 2016
07082a5
Add unit tests to test references and includesReferenceTo
May 4, 2016
191c63f
Correct the annotation formatting (string should be quoted)
May 10, 2016
bde7416
Update the "simple reference" docs as suggested by @malarzm
coudenysj May 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions docs/en/reference/annotations-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1191,8 +1191,11 @@ Optional attributes:
-
targetDocument - A |FQCN| of the target document.
-
simple - Create simple references and only store the referenced document's
identifier (e.g. ``MongoId``) instead of a `DBRef`_. Note that simple
simple - deprecated (use ``storeAs: id``)
-
storeAs - Indicates how to store the reference. ``id`` uses ``MongoId``,
``dbRef`` uses a `DBRef`_ without ``$db`` value and ``dbRefWithDb`` stores
a full `DBRef`_ (``$ref``, ``$id``, and ``$db``). Note that ``id``
references are not compatible with the discriminators.
-
cascade - Cascade Option
Expand Down Expand Up @@ -1258,8 +1261,11 @@ Optional attributes:
-
targetDocument - A |FQCN| of the target document.
-
simple - Create simple references and only store the referenced document's
identifier (e.g. ``MongoId``) instead of a `DBRef`_. Note that simple
simple - deprecated (use ``storeAs: id``)
-
storeAs - Indicates how to store the reference. ``id`` uses ``MongoId``,
``dbRef`` uses a `DBRef`_ without ``$db`` value and ``dbRefWithDb`` stores
a full `DBRef`_ (``$ref``, ``$id``, and ``$db``). Note that ``id``
references are not compatible with the discriminators.
-
cascade - Cascade Option
Expand Down
2 changes: 1 addition & 1 deletion docs/en/reference/complex-references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ the inverse side of a relationship.
You can create an `immutable`_ reference to one or many documents and specify
how that reference is to be loaded. The reference is immutable in that it is
defined only in the mapping, unlike a typical reference where a `MongoDBRef`_ or
identifier (for :ref:`simple_references`) is stored on the document itself.
identifier (see :ref:`storing_references`) is stored on the document itself.

The following options may be used for :ref:`one <reference_one>` and
:ref:`many <reference_many>` reference mappings:
Expand Down
2 changes: 1 addition & 1 deletion docs/en/reference/priming-references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ queries (one per discriminated class name).

.. note::

Priming is also compatible with :ref:`simple references <simple_references>`
Priming is also compatible with :ref:`simple references <storing_references>`
and discriminated references. When priming discriminated references, ODM
will issue one query per distinct class among the referenced document(s).

Expand Down
40 changes: 31 additions & 9 deletions docs/en/reference/reference-mapping.rst
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,14 @@ a certain class, you can optionally specify a default discriminator value:
song: Documents\Song
defaultDiscriminatorValue: album

.. _simple_references:
.. _storing_references:

Simple References
-----------------
Storing References
------------------

By default all references are stored as a `DBRef`_ object with the traditional
``$ref``, ``$id``, and ``$db`` fields (in that order). For references to
documents of a single collection, storing the collection and database names for
``$ref``, ``$id``, and (optionally) ``$db`` fields (in that order). For references to
documents of a single collection, storing the collection (and database) names for
each reference may be redundant. You can use simple references to store the
referenced document's identifier (e.g. ``MongoId``) instead of a `DBRef`_.

Expand All @@ -329,19 +329,19 @@ Example:
<?php

/**
* @ReferenceOne(targetDocument="Profile", simple=true)
* @ReferenceOne(targetDocument="Profile", storeAs="id")
*/
private $profile;

.. code-block:: xml

<reference-one target-document="Documents\Profile", simple="true" />
<reference-one target-document="Documents\Profile", store-as="id" />

.. code-block:: yaml

referenceOne:
profile:
simple: true
storeAs: id

Now, the ``profile`` field will only store the ``MongoId`` of the referenced
Profile document.
Expand All @@ -351,6 +351,28 @@ itself and any indexes on the reference field; however, simple references cannot
be used with discriminators, since there is no `DBRef`_ object in which to store
a discriminator value.

In addition to saving references as `DBRef`_ with ``$ref``, ``$id``, and ``$db``
fields and as ``MongoId``, it is possible to save references as `DBRef`_ without
the ``$db`` field. This solves problems when the database name changes (and also
reduces the amount of storage used).

The ``storeAs`` option has three possible values:

- **dbRefWithDb**: Uses a `DBRef`_ with ``$ref``, ``$id``, and ``$db`` fields (this is the default)
- **dbRef**: Uses a `DBRef`_ with ``$ref`` and ``$id``
- **id**: Uses a ``MongoId``

.. note::

The ``storeAs=id`` option used to be called a "simple reference". The old syntax is
still recognized (so using ``simple=true`` will imply ``storeAs=id``).

.. note::

For backwards compatibility ``storeAs=dbRefWithDb`` is the default, but
``storeAs=dbRef`` is the recommended setting.


Cascading Operations
--------------------

Expand Down Expand Up @@ -391,6 +413,6 @@ The valid values are:
- **remove** - cascade remove operation to referenced documents.
- **persist** - cascade persist operation to referenced documents.

.. _`DBRef`: http://docs.mongodb.org/manual/reference/database-references/#dbref
.. _`DBRef`: http://docs.mongodb.org/manual/reference/database-references/#dbrefs
.. |FQCN| raw:: html
<abbr title="Fully-Qualified Class Name">FQCN</abbr>
14 changes: 12 additions & 2 deletions doctrine-mongo-mapping.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@
<xs:attribute name="collectionClass" type="xs:string" />
</xs:complexType>

<xs:simpleType name="reference-store-as">
<xs:restriction base="xs:token">
<xs:enumeration value="id"/>
<xs:enumeration value="dbRef"/>
<xs:enumeration value="dbRefWithDb"/>
</xs:restriction>
</xs:simpleType>

<xs:complexType name="reference-one">
<xs:sequence>
<xs:element name="cascade" type="odm:cascade-type" minOccurs="0" />
Expand All @@ -125,7 +133,8 @@
<xs:attribute name="target-document" type="xs:string" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="fieldName" type="xs:NMTOKEN" />
<xs:attribute name="simple" type="xs:boolean" />
<xs:attribute name="simple" type="xs:boolean" /><!-- deprecated -->
<xs:attribute name="store-as" type="odm:reference-store-as" default="dbRefWithDb" />
<xs:attribute name="strategy" type="xs:NMTOKEN" default="pushAll" />
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" />
Expand All @@ -145,7 +154,8 @@
<xs:attribute name="target-document" type="xs:string" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="fieldName" type="xs:NMTOKEN" />
<xs:attribute name="simple" type="xs:boolean" />
<xs:attribute name="simple" type="xs:boolean" /><!-- deprecated -->
<xs:attribute name="store-as" type="odm:reference-store-as" default="dbRefWithDb" />
<xs:attribute name="strategy" type="xs:NMTOKEN" default="pushAll" />
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" />
Expand Down
7 changes: 5 additions & 2 deletions lib/Doctrine/ODM/MongoDB/DocumentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ public function createDBRef($document, array $referenceMapping = null)
);
}

if ( ! empty($referenceMapping['simple'])) {
if ($referenceMapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
if ($class->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION) {
throw MappingException::simpleReferenceMustNotTargetDiscriminatedDocument($referenceMapping['targetDocument']);
}
Expand All @@ -689,9 +689,12 @@ public function createDBRef($document, array $referenceMapping = null)
$dbRef = array(
'$ref' => $class->getCollection(),
'$id' => $class->getDatabaseIdentifierValue($id),
'$db' => $this->getDocumentDatabase($class->name)->getName(),
);

if ($referenceMapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB) {
Copy link
Member

@alcaeus alcaeus Apr 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've mentioned this in the original PR (#807 (comment)) and I'll mention it again: Expr::references and Expr::includesReferenceTo currently rely on the $db option being set when no targetDocument is given.

Correction: you're handling this in ClassMetadataInfo. Good job 👍

$dbRef['$db'] = $this->getDocumentDatabase($class->name)->getName();
}

/* If the class has a discriminator (field and value), use it. A child
* class that is not defined in the discriminator map may only have a
* discriminator field and no value, so default to the full class name.
Expand Down
5 changes: 3 additions & 2 deletions lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ private function generateHydratorClass(ClassMetadata $class, $hydratorClassName,
/** @ReferenceOne */
if (isset(\$data['%1\$s'])) {
\$reference = \$data['%1\$s'];
if (isset(\$this->class->fieldMappings['%2\$s']['simple']) && \$this->class->fieldMappings['%2\$s']['simple']) {
if (isset(\$this->class->fieldMappings['%2\$s']['storeAs']) && \$this->class->fieldMappings['%2\$s']['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
\$className = \$this->class->fieldMappings['%2\$s']['targetDocument'];
\$mongoId = \$reference;
} else {
Expand Down Expand Up @@ -291,7 +291,7 @@ private function generateHydratorClass(ClassMetadata $class, $hydratorClassName,
\$className = \$mapping['targetDocument'];
\$targetClass = \$this->dm->getClassMetadata(\$mapping['targetDocument']);
\$mappedByMapping = \$targetClass->fieldMappings[\$mapping['mappedBy']];
\$mappedByFieldName = isset(\$mappedByMapping['simple']) && \$mappedByMapping['simple'] ? \$mapping['mappedBy'] : \$mapping['mappedBy'].'.\$id';
\$mappedByFieldName = isset(\$mappedByMapping['storeAs']) && \$mappedByMapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID ? \$mapping['mappedBy'] : \$mapping['mappedBy'].'.\$id';
\$criteria = array_merge(
array(\$mappedByFieldName => \$data['_id']),
isset(\$this->class->fieldMappings['%2\$s']['criteria']) ? \$this->class->fieldMappings['%2\$s']['criteria'] : array()
Expand Down Expand Up @@ -366,6 +366,7 @@ private function generateHydratorClass(ClassMetadata $class, $hydratorClassName,
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\Hydrator\HydratorInterface;
use Doctrine\ODM\MongoDB\UnitOfWork;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;

/**
* THIS CLASS WAS GENERATED BY THE DOCTRINE ODM. DO NOT EDIT THIS FILE.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

namespace Doctrine\ODM\MongoDB\Mapping\Annotations;

use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
use Doctrine\ODM\MongoDB\Utility\CollectionHelper;

/**
Expand All @@ -30,7 +31,8 @@ final class ReferenceMany extends AbstractField
{
public $type = 'many';
public $reference = true;
public $simple = false;
public $simple = false; // @deprecated
public $storeAs = ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB;
public $targetDocument;
public $discriminatorField;
public $discriminatorMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

namespace Doctrine\ODM\MongoDB\Mapping\Annotations;

use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;

/**
* Specifies a one-to-one relationship to a different document
*
Expand All @@ -28,7 +30,8 @@ final class ReferenceOne extends AbstractField
{
public $type = 'one';
public $reference = true;
public $simple = false;
public $simple = false; // @deprecated
public $storeAs = ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB;
public $targetDocument;
public $discriminatorField;
public $discriminatorMap;
Expand Down
22 changes: 21 additions & 1 deletion lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ class ClassMetadataInfo implements \Doctrine\Common\Persistence\Mapping\ClassMet
const MANY = 'many';
const ONE = 'one';

/**
* The types of storeAs references
*/
const REFERENCE_STORE_AS_ID = 'id';
const REFERENCE_STORE_AS_DB_REF = 'dbRef';
const REFERENCE_STORE_AS_DB_REF_WITH_DB = 'dbRefWithDb';

/* The inheritance mapping types */
/**
* NONE means the class does not participate in an inheritance hierarchy
Expand Down Expand Up @@ -1181,7 +1188,20 @@ public function mapField(array $mapping)
$mapping['nullable'] = false;
}

if (isset($mapping['reference']) && ! empty($mapping['simple']) && ! isset($mapping['targetDocument'])) {
// Synchronize the "simple" and "storeAs" mapping information for backwards compatibility
if (isset($mapping['simple']) && ($mapping['simple'] === true || $mapping['simple'] === 'true')) {
$mapping['storeAs'] = ClassMetadataInfo::REFERENCE_STORE_AS_ID;
}
// Remove the "simple" mapping and use "storeAs" in all further logic
if (isset($mapping['simple'])) {
unset($mapping['simple']);
}

if (isset($mapping['reference'])
&& isset($mapping['storeAs'])
&& $mapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID
&& ! isset($mapping['targetDocument'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not having a targetDocument set is one case where we need to throw an exception - the other would be targetDocument being stored in a different database than the document storing the reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alcaeus I'm not quite sure how I can fetch the mapping for the targetDocument in the ClassMetadataInfo class.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately you can't, IMO that could be detected at the runtime but I have a feeling there's way more things than references that could bite you in such cases so that wouldn't be my main concern :)

) {
throw MappingException::simpleReferenceRequiresTargetDocument($this->name, $mapping['fieldName']);
}

Expand Down
3 changes: 2 additions & 1 deletion lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ private function addReferenceMapping(ClassMetadataInfo $class, $reference, $type
'orphanRemoval' => isset($attributes['orphan-removal']) ? ('true' === (string) $attributes['orphan-removal']) : false,
'type' => $type,
'reference' => true,
'simple' => isset($attributes['simple']) ? ('true' === (string) $attributes['simple']) : false,
'simple' => isset($attributes['simple']) ? ('true' === (string) $attributes['simple']) : false, // deprecated
'storeAs' => isset($attributes['store-as']) ? (string) $attributes['store-as'] : ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB,
'targetDocument' => isset($attributes['target-document']) ? (string) $attributes['target-document'] : null,
'name' => (string) $attributes['field'],
'strategy' => isset($attributes['strategy']) ? (string) $attributes['strategy'] : $defaultStrategy,
Expand Down
3 changes: 2 additions & 1 deletion lib/Doctrine/ODM/MongoDB/Mapping/Driver/YamlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,8 @@ private function addMappingFromReference(ClassMetadataInfo $class, $fieldName, $
'orphanRemoval' => isset($reference['orphanRemoval']) ? $reference['orphanRemoval'] : false,
'type' => $type,
'reference' => true,
'simple' => isset($reference['simple']) ? (boolean) $reference['simple'] : false,
'simple' => isset($reference['simple']) ? (boolean) $reference['simple'] : false, // deprecated
'storeAs' => isset($reference['storeAs']) ? (string) $reference['storeAs'] : ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB,
'targetDocument' => isset($reference['targetDocument']) ? $reference['targetDocument'] : null,
'fieldName' => $fieldName,
'strategy' => isset($reference['strategy']) ? (string) $reference['strategy'] : $defaultStrategy,
Expand Down
9 changes: 5 additions & 4 deletions lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Doctrine\MongoDB\CursorInterface;
use Doctrine\ODM\MongoDB\Cursor;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
use Doctrine\ODM\MongoDB\Utility\CollectionHelper;
use Doctrine\ODM\MongoDB\Hydrator\HydratorFactory;
use Doctrine\ODM\MongoDB\LockException;
Expand Down Expand Up @@ -666,7 +667,7 @@ private function loadReferenceManyCollectionOwningSide(PersistentCollectionInter
$sorted = isset($mapping['sort']) && $mapping['sort'];

foreach ($collection->getMongoData() as $key => $reference) {
if (isset($mapping['simple']) && $mapping['simple']) {
if (isset($mapping['storeAs']) && $mapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
$className = $mapping['targetDocument'];
$mongoId = $reference;
} else {
Expand Down Expand Up @@ -752,7 +753,7 @@ public function createReferenceManyInverseSideQuery(PersistentCollectionInterfac
$ownerClass = $this->dm->getClassMetadata(get_class($owner));
$targetClass = $this->dm->getClassMetadata($mapping['targetDocument']);
$mappedByMapping = isset($targetClass->fieldMappings[$mapping['mappedBy']]) ? $targetClass->fieldMappings[$mapping['mappedBy']] : array();
$mappedByFieldName = isset($mappedByMapping['simple']) && $mappedByMapping['simple'] ? $mapping['mappedBy'] : $mapping['mappedBy'] . '.$id';
$mappedByFieldName = isset($mappedByMapping['storeAs']) && $mappedByMapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID ? $mapping['mappedBy'] : $mapping['mappedBy'] . '.$id';
$criteria = $this->cm->merge(
array($mappedByFieldName => $ownerClass->getIdentifierObject($owner)),
$this->dm->getFilterCollection()->getFilterCriteria($targetClass),
Expand Down Expand Up @@ -994,7 +995,7 @@ private function prepareQueryElement($fieldName, $value = null, $class = null, $
// No further preparation unless we're dealing with a simple reference
// We can't have expressions in empty() with PHP < 5.5, so store it in a variable
$arrayValue = (array) $value;
if (empty($mapping['reference']) || empty($mapping['simple']) || empty($arrayValue)) {
if (empty($mapping['reference']) || $mapping['storeAs'] !== ClassMetadataInfo::REFERENCE_STORE_AS_ID || empty($arrayValue)) {
return array($fieldName, $value);
}

Expand Down Expand Up @@ -1106,7 +1107,7 @@ private function prepareQueryElement($fieldName, $value = null, $class = null, $
$objectPropertyIsId = $targetClass->isIdentifier($objectProperty);

// Prepare DBRef identifiers or the mapped field's property path
$fieldName = ($objectPropertyIsId && ! empty($mapping['reference']) && empty($mapping['simple']))
$fieldName = ($objectPropertyIsId && ! empty($mapping['reference']) && $mapping['storeAs'] !== ClassMetadataInfo::REFERENCE_STORE_AS_ID)
? $e[0] . '.$id'
: $e[0] . '.' . $objectPropertyPrefix . $targetMapping['name'];

Expand Down
15 changes: 13 additions & 2 deletions lib/Doctrine/ODM/MongoDB/Query/Expr.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
use Doctrine\ODM\MongoDB\Mapping\MappingException;

/**
Expand Down Expand Up @@ -73,12 +74,17 @@ public function references($document)
if ($this->currentField) {
$mapping = $this->getReferenceMapping();
$dbRef = $this->dm->createDBRef($document, $mapping);
$storeAs = array_key_exists('storeAs', $mapping) ? $mapping['storeAs'] : null;

if (isset($mapping['simple']) && $mapping['simple']) {
if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
$this->query[$mapping['name']] = $dbRef;
} else {
$keys = array('ref' => true, 'id' => true, 'db' => true);

if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF) {
unset($keys['db']);
}

if (isset($mapping['targetDocument'])) {
unset($keys['ref'], $keys['db']);
}
Expand Down Expand Up @@ -106,12 +112,17 @@ public function includesReferenceTo($document)
if ($this->currentField) {
$mapping = $this->getReferenceMapping();
$dbRef = $this->dm->createDBRef($document, $mapping);
$storeAs = array_key_exists('storeAs', $mapping) ? $mapping['storeAs'] : null;

if (isset($mapping['simple']) && $mapping['simple']) {
if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
$this->query[$mapping['name']] = $dbRef;
} else {
$keys = array('ref' => true, 'id' => true, 'db' => true);

if ($storeAs === ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF) {
unset($keys['db']);
}

if (isset($mapping['targetDocument'])) {
unset($keys['ref'], $keys['db']);
}
Expand Down
Loading