1
votes

In the following case,

Session s = getJcrSessionWithSimpleCredentials();
Node parent = getSomeNode(s).;
parent.addNode("firstChild","nt:unstructured");
parent.addNode("second/child","nt:unstructured");
s.save();

The first child will be saved, but second child will throw RepositoryExcepion, as there is slash "/" in the node name. Now I want to rollback my changes of creating both nodes.

How this can be handled in JCR / Jacrabbit ?

1
There's nothing you need to roll back. The "save" operation does not create the first node.Julian Reschke
I tested it again, the first node get's saved but second node doesn't. One correction exception is "PathNotFoundException" for "child" as parent path is missing till "somenode/second" is not present. Well, but my intention is any error in creating node should rollback all changes.Dileepa
That's not supposed to happen. How did you test that the first node was saved?Julian Reschke

1 Answers

2
votes
Session s = getJcrSessionWithSimpleCredentials();
Node parent = getSomeNode(s).;
parent.addNode("firstChild","nt:unstructured");
parent.addNode("second/child","nt:unstructured");
s.save();

If, as you say, the line parent.addNode("second/child","nt:unstructured") throws an exception, s.save() is not executed (the line is never reached) and others will not see the changes you made to the repository.

In your session, however, the addition of firstChild is still going to be visible.

You can refresh the session to give up the changes local to your session. As a short example:

try {
    Session s = getJcrSessionWithSimpleCredentials();
    Node parent = getSomeNode(s).;
    parent.addNode("firstChild","nt:unstructured");
    parent.addNode("second/child","nt:unstructured");
    s.save();
} catch (PathNotFoundException ex) {
    // log the exception
    // give up all unsaved changes made in your session
    s.refresh(false); 
}

Please mind that this is just meant as a concise example. Personally, I'd check for the existence of the parent before attempting to save the node rather than catch PathNotFoundException. The point is, you can execute a session refresh when you want to give up the unsaved changes. Be it in a catch block or a branch of a conditional expression.

To quote the Javadoc for Session#refresh(boolean keepChanges)

If keepChanges is false, this method discards all pending changes currently recorded in this Session and returns all items to reflect the current saved state. Outside a transaction this state is simply the current state of persistent storage. Within a transaction, this state will reflect persistent storage as modified by changes that have been saved but not yet committed.

As for transaction support, you can read more here.