Hi,
Sorry to chime in late...
I see the issues of Vidar and these are caused by the
PersistableValueMap introducing its own transient space ontop of the JCR
transient space.
When the PersistableValueMap transient space is saved (save() call), the
data is written to the JCR transient space and then directly to the JCR
persistent space by calling the JCR save method.
I see the problem. In fact, even if the Sling API would allow for full
CRUD, particularly creating resources, Vidar's use case cannot be
implemented using the PersistableValueMap.
How about this:
* Enable the PersistableValueMap to write through to the JCR
transient space on put().
* Write-through is configurable on a global level (in the
JcrResourceResolver providing the PersistableValueMap
instances upon adapt()). By default it is switched off
(backwards compatiblity).
* Write-through can also be switched on/off on a per-instance
level of the PersistableValueMap object (setWriteThrough(boolean))
* PersistableValueMap.save() first writes back local changes
not already stored using write-through and then calls node.save()
* PersistableValueMap.reset() drops local changes not already stored
using write-through and then calls node.refresh(false)
* When we finally do full CRUD in the ResourceResolver, we should
add save/reset methods, which would call Session.save() or
refresh(false), resp. For now the Session methods must be called
directly.
WDYT ?
Regards
Felix
On 11.02.2010 17:02, Vidar Ramdal wrote:
> JcrModifiablePropertyMap works by storing all changes in an internal
> cache. Upon save() the cached changes are written to the
> javax.jcr.Node, and the node is save()d.
>
> This makes sequences such as this impossible:
> try {
> // Modify a property through PersistableValueMap
> PersistableValueMap props = resource.adaptTo(PersistableValueMap.class);
> props.put("prop", value);
> props.save();
> // Do some other, unrelated changes
> Node sibling = resource.adaptTo(Node.class).getParent().addNode("child");
> sibling.doSomeChange(); // This may throw an exception
> session.save();
> } catch(Exception e) {
> session.refresh(false); // Cancel the pending changes of this session
> }
>
> The idea is to save all changes to the repository in one single
> session.save(). If anything fails, the session is reverted.
> This doesn't work because the properties of PersistableValueMap is not
> written to the node until PersistableValueMap.save(), and by then, it
> is too late to revert the session, as the changes of
> PersistableValueMap are already persisted.
>
> We could make such operations easier by introducing a new method
> PersistableValueMap.write() (in lack of a better name).
> In case of JcrModifiablePropertyMap, most of save() would be moved to
> write(), leaving out node.save().
>
> So that JcrModifiablePropertyMap.save() would be:
> public void save() throws PersistenceException {
> this.write();
> node.save();
> }
>
> In the code example above, replacing props.save() with props.write()
> should give the desired functionality.
>
> WDYT?
>