jakarta-eejcrmodeshapewildfly-8

Only get node with unversioned changes - JCR ModeShape


We have a couple of nodes in JCR which are supposed to versioned at midnight. Of course we only want to create a new version if there was a change to this node since the last time it was versioned. Is there a way to get all nodes with unversioned changes without getting all, iterating over them and comparing the timestamp of the last change to the latest version?


Solution

  • JCR 2.0 includes a built-in standard mixin, mix:lastModified that is defined like this:

    [mix:lastModified] mixin 
      - jcr:lastModified (date) 
      - jcr:lastModifiedBy (string)
    

    To use it, simply add it as a mixin to a node using Node.addMixin("mix:lastModified"), or if you're using a custom node type simply change your custom node type extend it. When you change one of these nodes, ModeShape will automatically update the two properties upon save. (There is also a built-in mix:created that has jcr:created and jcr:createdBy properties, and works in an analogous manner.)

    To find all nodes that were modified after some time, issue a query:

    SELECT [jcr:path]
    FROM [mix:lastModified] AS node
    WHERE [jcr:lastModified] >= CAST('2014-06-01T11:00:00.000' AS DATE)
    

    If you need more than the path, it might be easiest to use QueryResult.getNodes() and iterate over the Node instances (rather than use the getRows()).

    This last query will find all nodes regardless of type, so if you want to find all nodes of a given type (e.g., acme:dataNode) on which mix:lastModified was added as mixin and on which some properties were changed since some date, you need to use a join:

    SELECT modified.[jcr:path], myNode.[acme:myDataProperty]
    FROM [acme:dataNode] AS myNode
    JOIN [mix:lastModified] AS modified ON ISSAMENODE(myNode,modified)
    WHERE modified.[jcr:lastModified] >= CAST('2014-06-01T11:00:00.000' AS DATE)
    

    On the other hand, if your custom node type extends mix:lastModified like:

    [acme:customType] > mix:lastModified, mix:versionable
      - acme:customProperty (string)
    

    then your query can be a little simpler and select from that node type (without a join):

    SELECT [jcr:path], [acme:customProperty]
    FROM [amce:customType] AS node
    WHERE [jcr:lastModified] >= CAST('2014-06-01T11:00:00.000' AS DATE)
    

    After all, the mix:lastModified properties are visible on your custom type and thus are visible in the acme:customType node type.