Details
Description
If you delete a node with mixin mix:versionable and move another node with the same mixin in its place (that is, it now has the very same path), you get a ConstraintViolationException that complains that you are changing protected properties. Thus, this operation is impossible to perform within one transaction. But splitting it into two transactions is risky in many cases. It seems there is a mechanism that checks for changes of protected properties, and ignores that this is now a different node.
If you have two nodes /somewhere/1 and /somewhere/2 which both are nt:unstructured and have mix:versionable, the following code triggers an exception but shouldn't:
session.removeItem("/somewhere/2");
session.move("/somewhere/1", "/somewhere/2");
session.save();
The actual stacktrace thrown is:
javax.jcr.nodetype.ConstraintViolationException: OakConstraint0100: Property is protected: jcr:versionHistory
at org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:226)
at org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryException(CommitFailedException.java:213)
at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.newRepositoryException(SessionDelegate.java:669)
at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegate.java:495)
at org.apache.jackrabbit.oak.jcr.session.SessionImpl$8.performVoid(SessionImpl.java:420)
at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.performVoid(SessionDelegate.java:273)
at org.apache.jackrabbit.oak.jcr.session.SessionImpl.save(SessionImpl.java:417)
at org.apache.sling.jcr.oak.server.internal.TcclWrappingJackrabbitSession.save(TcclWrappingJackrabbitSession.java:212)
at org.apache.jsp.apps.composum.prototype.assets.pagesintegration.hpsx.hpsx_jsp._jspService(hpsx_jsp.java:115)
at org.apache.sling.scripting.jsp.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
(irrelevant sling stuff omitted)
Caused by: org.apache.jackrabbit.oak.api.CommitFailedException: OakConstraint0100: Property is protected: jcr:versionHistory
at org.apache.jackrabbit.oak.plugins.version.VersionEditor.throwProtected(VersionEditor.java:257)
at org.apache.jackrabbit.oak.plugins.version.VersionEditor.propertyChanged(VersionEditor.java:152)
at org.apache.jackrabbit.oak.spi.commit.VisibleEditor.propertyChanged(VisibleEditor.java:73)
at org.apache.jackrabbit.oak.spi.commit.EditorDiff.propertyChanged(EditorDiff.java:92)
at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareProperties(SegmentNodeState.java:664)
at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:558)
at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:147)
at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:495)
at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:651)
at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:147)
at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:422)
at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:651)
at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:147)
at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:422)
at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:651)
at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:147)
at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:422)
at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:651)
at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:147)
at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:598)
at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:147)
at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:422)
at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:651)
at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:147)
at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:422)
at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:651)
at org.apache.jackrabbit.oak.spi.commit.EditorDiff.process(EditorDiff.java:51)
at org.apache.jackrabbit.oak.spi.commit.EditorHook.processCommit(EditorHook.java:54)
at org.apache.jackrabbit.oak.spi.commit.CompositeHook.processCommit(CompositeHook.java:60)
at org.apache.jackrabbit.oak.plugins.version.VersionHook.processCommit(VersionHook.java:86)
at org.apache.jackrabbit.oak.spi.commit.CompositeHook.processCommit(CompositeHook.java:60)
at org.apache.jackrabbit.oak.spi.commit.CompositeHook.processCommit(CompositeHook.java:60)
at org.apache.jackrabbit.oak.segment.scheduler.Commit.apply(Commit.java:99)
at org.apache.jackrabbit.oak.segment.scheduler.LockBasedScheduler.execute(LockBasedScheduler.java:299)
at org.apache.jackrabbit.oak.segment.scheduler.LockBasedScheduler.schedule(LockBasedScheduler.java:270)
at org.apache.jackrabbit.oak.segment.SegmentNodeStore.merge(SegmentNodeStore.java:211)
at org.apache.jackrabbit.oak.core.MutableRoot.commit(MutableRoot.java:251)
at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.commit(SessionDelegate.java:346)
at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegate.java:493)