Uploaded image for project: 'ModeShape'
  1. ModeShape
  2. MODE-1117

The "jcr:predecessors" property for "mix:versionable" nodes is set incorrectly

    Details

    • Steps to Reproduce:
      Hide

      Create a versionable node (which is left in the checked-out phase), check it in (to create the initial version), then repeatedly:
      1) check out the node
      2) modify it
      3) check in the node

      When completed, look at (or print out) the node's version history, and particularly look at the "jcr:predecessors" and "jcr:successors" properties. Even though no merging operation is performed, these property values will contain more than one value.

      Show
      Create a versionable node (which is left in the checked-out phase), check it in (to create the initial version), then repeatedly: 1) check out the node 2) modify it 3) check in the node When completed, look at (or print out) the node's version history, and particularly look at the "jcr:predecessors" and "jcr:successors" properties. Even though no merging operation is performed, these property values will contain more than one value.

      Description

      Upon code review during investigation of MODE-1114, it was discovered that the "jcr:predecessors" property on "mix:versionable" nodes and on "nt:version" nodes (in the version history) appears to be set incorrectly - upon checkin, the value is set not only to the previous base version, but also to all earlier versions as well.

      Consider four versions of a node, called Version1, Version2, Version3, and Version4 (with UUIDs of uuidV1, uuidV2, uuidV3, and uuidV4 respectively), where successive versions are created by checking out the node, modifying it, and checking it back in. With the current approach, these versions would have the following predecessors and successors:

        V1
        - jcr:uuid = uuidV1
        - jcr:predecessor = []
        - jcr:successors = [uuidV2,uuidV3,uuidV4]
        V2
        - jcr:uuid = uuidV2
        - jcr:predecessor = [uuidV1]
        - jcr:successors = [uuidV3,uuidV4]
        V3
        - jcr:uuid = uuidV4
        - jcr:predecessors = [uuidV2,uuidV1]
        - jcr:successors = [uuidV4]
        V4
        - jcr:uuid = uuidV4
        - jcr:predecessors = [uuidV3,uuidV2,uuidV1]
      

      The JSR-283 (JCR 2.0) specification says the following in Section 15.2.1.4:

      Version[] Version.getPredecessors()

      returns the direct predecessors of this Version. Under simple versioning this set will be at most of size 1. Under full versioning, this set maybe of size greater than 1, indicating a merge within the version graph.

      Therefore, I think the correct behavior for checkin (as opposed to merge) is to simply set the "jcr:predecessor" property to an array containing only the "jcr:baseVersion" value at the beginning of the checkin call. With this new approach, the versions in the example used above would have the following predecessors and successors:

        V1
        - jcr:uuid = uuidV1
        - jcr:predecessor = []
        - jcr:successors = [uuidV2]
        V2
        - jcr:uuid = uuidV2
        - jcr:predecessor = [uuidV1]
        - jcr:successors = [uuidV3]
        V3
        - jcr:uuid = uuidV4
        - jcr:predecessor = [uuidV2]
        - jcr:successors = [uuidV3]
        V4
        - jcr:uuid = uuidV4
        - jcr:predecessor = [uuidV3]
      

      I think this is actually what is intended by the specification during non-merge checkins.

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                rhauch Randall Hauch
                Reporter:
                rhauch Randall Hauch
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: