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? >