Question

Say I have two simple Documents like this, where a person can have many papers, but a paper can only belong to one person.

namespace Dashboard\Document;

use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/** @ODM\Document(db="testing", collection="person")
 * @ODM\InheritanceType("COLLECTION_PER_CLASS")
 */
class Person
{
/**
 * @ODM\Id
 */
protected $id;

/** @ODM\Field(type="string") */
protected $slug;

/** @ODM\Field(type="string") */
protected $name;

/** @ODM\ReferenceMany(targetDocument="Paper", cascade={"all"}) */
protected $papers;


public function __get($property) {
    return $this->$property;
}

public function __set($property, $value) {
    $this->$property = $value;
}

public function toArray() {
    return get_object_vars($this);
}
}
namespace Dashboard\Document;

use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/** @ODM\Document(db="testing", collection="paper")
 * @ODM\InheritanceType("COLLECTION_PER_CLASS")
 */
class Paper
{
/**
 * @ODM\Id
 */
protected $id;

/** @ODM\Field(type="string") */
protected $name;

/** @ODM\ReferenceOne(targetDocument="Person", cascade={"all"}) */
protected $person;


public function __get($property) {
    return $this->$property;
}

public function __set($property, $value) {
    $this->$property = $value;
}

public function toArray() {
    return get_object_vars($this);
}
}

I thought I read somewhere when you create a reference on one end, Doctrine ODM will auto create the references on both sides for you. So if I execute the statement below, I will see a reference to Person from a Paper document, AS WELL AS references to Paper(s) in a Person document.

//For demo sake; $person already contains a Person document
try {
    $paper = $dm->getRepository('\Dashboard\Document\Paper')
            ->find($paperId);
} catch (\Doctrine\ODM\MongoDB\MongoDBException $e) {
    $this->setStatusFailure($e->getMessage());
    $this->sendResponse();
}    

$paper->person = $person;
$dm->persist($paper);
$dm->flush();

When I do that, and check the mongodb, the reference from paper-->person is there. But I see no reference person-->paper shown in the db. I thought the cascade annotations helped with this, but obviously I'm missing something.

How can I ensure the reference is contained on both ends, so I can run queries to see all the papers that belong a single person? Does this have to be done manually, or can I have doctrine handle this for me?

UPDATE

The first paragraph on this page made me think it was possible.

http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/bidirectional-references.html

Was it helpful?

Solution

Turns out I should have read that whole page. If I use mappedBy & inversedBy, and always persist the document that has inversedBy in it's Annotation, then I get that bi-directional relationship

/** @ODM\ReferenceOne(targetDocument="Person", cascade={"all"}, inversedBy="papers") */
protected $person;

//Will give me a relationship I can query on both sides
$person->papers->add($paper);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top