PHPCR ODM replace document

dbu edited this page Mar 12, 2013 · 2 revisions
Clone this wiki locally

PHPCR is different than a relational database in the sense that you can want to replace an existing document with a totally different one, at the same repository path - so essentially replacing the document with the same id with a totally different one.

Use case

When using the symfony2 form layer and mapping a child into the form, we can happen with situations where we need to replace a document completely. If the userland code would have to detect that the document has been replaced, remove the old document, flush and then add the new document, that would be an ugly hack. See for example this pull request.

Existing code

A first attempt at handling replacing documents as it happens in forms was made in https://github.com/doctrine/phpcr-odm/pull/253 . there are a couple of problems however:

  • if both the old and the new document have a child with the same name, the merge that is triggered, fails
  • if they have different children, the old children are not removed
  • you can not replace a document with a document of a different class

Solution idea

Lukas and David came up with the idea to have an explicit replace method to handle the various cases. You could replace the document, but merge any children, or completely remove the children of the old document and only add children of the new document. This would be controlled when calling replace.

For cascading, we should add an additional option to tell if CASCADE_PERSIST is meant to merge children or to replace children. We would do that as a separate option in a child/children mapping that each would apply to just the child/children mapped there. The direct child would replace (by removing all properties and translations on the phpcr node and adding the new fields as properties) the existing child if it is new, the option would control whether to merge or replace children of those children.