1
votes

I have a scenario where a repository contains several version nodes that don't reference any mix:versionable nodes. This is because those versionable nodes have been removed from repository but not their corresponding versions.

This is causing that the JackRabbit Garbage collector cannot remove some files from datastore, because there are versions that still reference them, and consequently the disk space is not properly freed.

I tried to manually remove those versions with the following algorithm:

  1. Obtain a version by its path, let's say: /jcr:system/jcr:versionStorage/40/05/a9/4005a9b2-51d1-4ed1-8c30-934409e05f86/1.14/jcr:frozenNode
  2. Get the jcr:frozenUuid property from the obtained node
  3. Get the node by identifier, using the frozenUuid from step 2
  4. If no such node exists, remove the version

But in the last step I get the following exception:

javax.jcr.nodetype.ConstraintViolationException: Unable to perform operation. Node is protected.

So, my question is. How can I remove the version nodes that are unused?

I'm using jackrabbit-2.2.13.

2

2 Answers

0
votes

This is how I remove my versions...

String nodePath...
String versionName...
Session session...

VersionManager versionManager = session.getWorkspace().getVersionManager()
VersionHistory versionHistory = versionManager.getVersionHistory(nodePath);
versionHistory.removeVersion(versionName);
0
votes

I think this will help you to traverse all the versions so that you can remove or restore.

        Node vs = session.getRootNode().getNode("jcr:system").getNode("jcr:versionStorage");
        Version v = traverseVersionStorage(vs, 0);

        private static Version traverseVersionStorage(Node n, int level)
                throws Exception {
            Version v = null;
            for (NodeIterator it = n.getNodes(); it.hasNext();) {
                Node n2 = it.nextNode();
                if (n2 instanceof Version && !n2.getName().startsWith("jcr:")) {
                    v = (Version) n2;
                    System.out.println("version " + n2.getName() + " of node "+ n2.getParent().getName() + ":");
                    Node n3 = n2.getNode("jcr:frozenNode");
                    VersionManager vman=session.getWorkspace().getVersionManager();
                        Node parent=n3.getParent();     
                        System.out.println(parent.getName());
                        vman.restore("/any/path/where/to/restore", v, true);
                        session.save();
                    }
                Version v2 = traverseVersionStorage(n2, level + 1);
                v = v == null ? v2 : v;
            }
            return v;
        }

below code is to traverse all versions of a node and remove by versionName

           VersionManager versionManager=jcrsession.getWorkspace().getVersionManager();
           VersionHistory vHistory=versionManager.getVersionHistory("/absolute/path/of/node/which/versions/to/be/removed");

                for (VersionIterator pt = vHistory.getAllVersions(); pt.hasNext();) 
                    {
                       Version p = pt.nextVersion();
                       if(p.getName()!="jcr:rootVersion")
                        {
                         vHistory.removeVersion(p.getName());
                        }
                    }