You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-issues@jackrabbit.apache.org by "Marcel Reutegger (JIRA)" <ji...@apache.org> on 2015/01/19 11:20:34 UTC

[jira] [Created] (OAK-2411) Upgrade may fail with constraint exception

Marcel Reutegger created OAK-2411:
-------------------------------------

             Summary: Upgrade may fail with constraint exception
                 Key: OAK-2411
                 URL: https://issues.apache.org/jira/browse/OAK-2411
             Project: Jackrabbit Oak
          Issue Type: Bug
          Components: core
    Affects Versions: 1.1.4, 1.0.9
            Reporter: Marcel Reutegger
            Assignee: Marcel Reutegger
            Priority: Minor
             Fix For: 1.0.10, 1.1.5


A repository upgrade to MongoMK sometimes fails with a constraint exception in PrivilegeValidator.childNodeChanged():

{noformat}
18074 [main] ERROR org.apache.jackrabbit.oak.security.user.UserInitializer - Failed to initialize user content.
org.apache.jackrabbit.oak.api.CommitFailedException: OakConstraint0041: Attempt to modify existing privilege definition jcr:nodeTypeManagement
	at org.apache.jackrabbit.oak.security.privilege.PrivilegeValidator.childNodeChanged(PrivilegeValidator.java:109)
	at org.apache.jackrabbit.oak.security.privilege.PrivilegeValidator.childNodeChanged(PrivilegeValidator.java:47)
	at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:143)
	at org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState.compareAgainstBaseState(MemoryNodeState.java:155)
{noformat}

The problem is related to the way {{NodeStateDiff.childNodeChanged()}} is specified:

bq. Called for all child nodes that *may* contain changes between the before and after states. The comparison implementation is expected to make an effort to avoid calling this method on child nodes under which nothing has changed.

When the upgrade runs, {{PriviledgeValidator.childNodeChanged()}} is called even though there isn't actually a difference between the before and after state.

On merge() the MemoryNodeStore squeezes the current NodeState (in {{MemoryNodeStoreBranch.setRoot()}}). This operation turns ModifiedNodeStates into equivalent MemoryNodeStates. When the hooks later process the changes, the node state comparison happens for a state that was squeezed with one that wasn't. This leads to {{MemoryNodeState.compareAgainstBaseState()}} calls where {{after != before}} and therefore {{diff.childNodeChanged()}} is called, even though the actual data of the states are equal.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)