I have a php object mapping to a mongodb document(called Node) with a structure
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
class Node{
/**
* @MongoDB\Id
*/
protected $id;
/**
* @MongoDB\String
*/
protected $domain;
/**
* @MongoDB\ReferenceMany(targetDocument="NodeItem",cascade=
* {"persist"},simple="true")
*/
protected $items = array();
//getter and setters below
}
And a referenced document called, NodeItem,
class NodeItem {
/**
* @MongoDB\Id
*/
protected $id;
/**
* @MongoDB\String
*/
protected $name;
/**
* @MongoDB\ReferenceOne(targetDocument="Node", cascade={"persist"},
* simple="true")
*/
protected Node;
//setter and getters
}
As reflected by the annotations above 'Node' references MANY 'NodeItems' stored in a $items array and 'NodeItems' references ONE 'Node'. So those are bi-directional referenced collections.
My Question is how to effectively delete a few 'NodeItem' documents from its collection (based on the array of available ids), so that the deleted NodeItem documents are also deleted from the $items array references in 'Node' (cascaded delete I think is what I am asking for?).
I wrote a function that has code like this :
$qb = $this->dm->createQueryBuilder('SomeBundleBundle:NodeItem');
/*
* deletes from NodeItem collection
*/
foreach($NodeItemsArray as $itemId){
$qb->remove()->field('id')->equals($itemId)->getQuery()->execute();
}
But the above function only deletes the documents from NodeItem collection, but the associated items in the $items array of 'Node' are not deleted. Also, the {cascade:persist} in the annotations doesn't seem to help. The code is implemented in Symfony 2 framework
Some help is appreciated !
Madarco :
The only way to achieve that is with a listener on the onRemove event.\n\nBut has mentioned by @jmikola, you'll have to use the $dm->remove() method, and not the QueryBuilder (since it doesn't support events yet).\n\n\n\nso, to delete the Item do:\n\n//Get the NodeItem you want in the items array and delete it:\n$items = $node->getItems();\n$dm->remove($items->get(2)); //Remove the third item as an example\n\n\n\n\nAnd register the event:\n\nclass CascadeNodeDeleterListener {\n public function preRemove(LifecycleEventArgs $eventArgs) {\n\n $odm = $eventArgs->getDocumentManager(); /* @var $odm DocumentManager */\n $object = $eventArgs->getDocument();\n if($object instanceOf NodeItem) {\n $node = $object->getNode();\n $items = $node->getItems();\n $items->removeElement($object);\n $class = $dm->getClassMetadata(get_class($node));\n $dm->getUnitOfWork()->recomputeSingleDocumentChangeSet($class, $node);\n }\n\n }\n}\n\n\nIn services.yml:\n\n <service id=\"listener\" class=\"CascadeNodeDeleterListener\">\n <tag name=\"doctrine.common.event_listener\" event=\"onRemove\" />\n </service>\n\n\nSee Doctrine ODM Events from more info.",
2013-05-01T07:36:54