4 Replies Latest reply on Jan 14, 2016 1:53 AM by asmierzchalski

    Removing all versions of a node which was copied

    asmierzchalski

      Hello together,

       

      i have following scenario:

      I'm adding a node with the mixin type versionable. After that i check the node out to update a property, save the node and checkin. Now i copy the node. If i try to remove now all versions of the original node to remove the node itself i'm getting a 'javax.jcr.ReferentialIntegrityException: org.modeshape.jcr.cache.ReferentialIntegrityException'.

       

      That's my example code:

      try {
               Credentials creds = new SimpleCredentials("admin", "admin".toCharArray());
      
      
               Session session = repo.login(creds);
      
      
               String folderPath = "/uploads";
      
      
               VersionManager versionManager = session.getWorkspace().getVersionManager();
               // create original node
               Node node = session.getNode(folderPath);
               Node originalNode = node.addNode("originalNode", NodeType.NT_FILE);
               originalNode.addMixin(NodeType.MIX_VERSIONABLE);
               originalNode.addMixin(NodeType.MIX_TITLE);
               Node contentNode = originalNode.addNode(JcrConstants.JCR_CONTENT,
                                                       JcrConstants.NT_RESOURCE);
               contentNode.setProperty(JcrConstants.JCR_DATA,
                                       session.getValueFactory().createBinary(this.getClass().getResourceAsStream("/my-repository-config.json")));
               System.out.println("Original node added.");
               session.save();
               // update original node
               versionManager.checkout(originalNode.getPath());
               originalNode.setProperty(Property.JCR_TITLE, "originalNode");
               session.save();
               versionManager.checkin(originalNode.getPath());
               System.out.println("Original node updated.");
      
      
               // copy original node
               session.getWorkspace().copy(originalNode.getPath(), "/uploads/copiedNode");
               System.out.println("Node has been copied.");
      
      
               // delete all versions
               VersionHistory history = versionManager.getVersionHistory(originalNode.getPath());
               VersionIterator it = history.getAllVersions();
               while (it.hasNext()) {
                  Version version = it.nextVersion();
                  history.removeVersion(version.getName());
               }
               System.out.println("All versions of original node removed.");
               // delete original node
               originalNode.remove();
               System.out.println("Original node removed.");
               session.save();
      
      
               session.logout();
            }
            catch (Exception e) {
               e.printStackTrace();
      }
      

      I am using the ModeShape version 4.5.0-Final.

       

      My question is now, am i doing something wrong or is that a bug? In my eyes the original node shouldn't have relations to the copied node.

       

      Greetings

      Adam

        • 1. Re: Removing all versions of a node which was copied
          hchiorean

          can you post a gist of the full exception please ?

           

          Versioning is a very complex endeavor, especially since your nodes are referencing binary values and you are using the default [nt:file] which does not have an explicit OPV, meaning its OPV defaults to "copy".

          • 2. Re: Removing all versions of a node which was copied
            asmierzchalski

            Here is the whole exception:

             

            javax.jcr.ReferentialIntegrityException: org.modeshape.jcr.cache.ReferentialIntegrityException: Cannot remove the nodes: '[a69d00a317f1e750143e65-b287-40ff-a8c4-ec07f6a57ce0, a69d00a317f1e74dd6917d-be2c-466e-b9ac-6d4f6e491269, a69d00a317f1e714098c94-ca1c-41c5-84ce-5222e8438b06]' because there are existing nodes: '[a69d00a317f1e74f1e537a-e88c-4447-b57a-5454446250fc, a69d00a7505d644f1e537a-e88c-4447-b57a-5454446250fc]' which have strong references towards them.

              at org.modeshape.jcr.JcrVersionHistoryNode.removeVersion(JcrVersionHistoryNode.java:264)

              at org.modeshape.jcr.JcrVersionHistoryNode.removeVersion(JcrVersionHistoryNode.java:182)

              at de.doubleslash.modeshape.versionexceptionbug.impl.CopyAndRemoveTest.showProblem(CopyAndRemoveTest.java:86)

              at de.doubleslash.modeshape.versionexceptionbug.impl.CopyAndRemoveTest.testCopyAndRemove(CopyAndRemoveTest.java:33)

              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

              at java.lang.reflect.Method.invoke(Method.java:601)

              at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)

              at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

              at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)

              at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

              at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)

              at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)

              at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)

              at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)

              at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)

              at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)

              at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)

              at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)

              at org.junit.runners.ParentRunner.run(ParentRunner.java:309)

              at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)

              at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)

              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)

              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)

              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

            Caused by: org.modeshape.jcr.cache.ReferentialIntegrityException: Cannot remove the nodes: '[a69d00a317f1e750143e65-b287-40ff-a8c4-ec07f6a57ce0, a69d00a317f1e74dd6917d-be2c-466e-b9ac-6d4f6e491269, a69d00a317f1e714098c94-ca1c-41c5-84ce-5222e8438b06]' because there are existing nodes: '[a69d00a317f1e74f1e537a-e88c-4447-b57a-5454446250fc, a69d00a7505d644f1e537a-e88c-4447-b57a-5454446250fc]' which have strong references towards them.

              at org.modeshape.jcr.cache.document.WritableSessionCache.persistChanges(WritableSessionCache.java:1419)

              at org.modeshape.jcr.cache.document.WritableSessionCache.save(WritableSessionCache.java:477)

              at org.modeshape.jcr.cache.document.WritableSessionCache.save(WritableSessionCache.java:432)

              at org.modeshape.jcr.cache.SessionCacheWrapper.save(SessionCacheWrapper.java:83)

              at org.modeshape.jcr.JcrSession$SystemSessionCache.save(JcrSession.java:2464)

              at org.modeshape.jcr.JcrVersionHistoryNode.removeVersion(JcrVersionHistoryNode.java:261)

              ... 26 more

             

             

            I also tried the case with the nodetype [nt:folder] which encounters the same problem.

            • 3. Re: Removing all versions of a node which was copied
              hchiorean

              The failure is caused by the fact the the copied node has a strong reference to the version which you're attempting to remove. Unfortunately the JCR spec is highly ambiguous regarding what should happen when you copy versionable nodes.

              As such, this requires further investigation. Feel free to log a JIRA issue for this.

              • 4. Re: Removing all versions of a node which was copied
                asmierzchalski

                Thanks for your investigation!

                As you mentioned i created a JIRA issue for this: [MODE-2560] Removing of all versions of a copied node - JBoss Issue Tracker