Hi,

I'm trying to make a content management system using JSR170 and the Jackrabbit implementation using ORM-persistence connecting to a PostgreSQL.

I think I have discovered a bug in jackrabbit when trying to delete several nodes using SameNameSibling.

I have developed a test you can place in:

src/test/org/apache/jackrabbit/test/api/

and add the testCase to the suite in:

src/test/org/apache/jackrabbit/test/api/TestAll.java
> suite.addTestSuite(RemoveSameNameSiblingNodesTest.class);

The structure of the test is the following one:
1º I add a first topNode under the rootNode.
2º I add 4 nodes with the same path (with no properties to avoid complexity of the test)
3º Later, I get a NodeIterator to get the 4 previous added nodes:
> NodeIterator it = topNode.getNodes(myNodePath);
4º Now, this is the suspect BUG, inside the while loop getting the nodes, I make a call to the remove() item method. If I save each change on the parent node, you can see that every remove operation have a strange behaviour and when you are removing the third item it tries to delete the root node!!!! (You can see the dump output of the test)

You can avoid this bug saving the session or the rootnode outside the while loop.

Best regards,
 Javier
package org.apache.jackrabbit.test.api;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Value;

import org.apache.jackrabbit.test.AbstractJCRTest;

public class RemoveSameNameSiblingNodesTest extends AbstractJCRTest {

	public void testRemoveSameSiblingNodes() throws Exception{
		String topNodePath = "topNode";
		String myNodePath = "MyTestNode";
		Node topNode = testRootNode.addNode(topNodePath);
		testRootNode.save();
		dump(topNode);
		// creation of 4 nt:unstructured nodes under the topNode
		for (int i = 0; i < 4; i++) {
			Node child = topNode.addNode(myNodePath);
		}
		superuser.save();
		System.out.println("After creation of 4 nt:unstructured nodes");
		dump(topNode);
		assertEquals("There is no 4 nodes created", 4, topNode.getNodes(myNodePath).getSize());

		// now, we try to delete the 4 nodes with namesibling: MyTestNode,
		// MyTestNode[2], MyTestNode[3]...
		NodeIterator it = topNode.getNodes(myNodePath);
		int i = 1;
		while (it.hasNext()) {
			Node node = (Node) it.next();
			node.remove();
			System.out.println("After deletion of the node number: " + i);
			dump(topNode);
			i++;
			// if you save each change instead of doing it outside the while loop it doesn't work!!!
			// comment the next line to get it works!!!
			topNode.save();
		}
		topNode.save();
	}

	public static void dump(Node n) throws RepositoryException {
		System.out.println(n.getPath());
		PropertyIterator pit = n.getProperties();
		while (pit.hasNext()) {
			Property p = pit.nextProperty();
			System.out.println(p.getPath() + "=");
			if (p.getDefinition().isMultiple()) {
				Value[] values = p.getValues();
				for (int i = 0; i < values.length; i++) {
					if (i > 0)
						System.out.println(",");
					System.out.println(values[i].getString());
				}
			} else {
				System.out.println(p.getString());
			}
			System.out.println("");
		}
		NodeIterator nit = n.getNodes();
		while (nit.hasNext()) {
			Node cn = nit.nextNode();
			dump(cn);
		}
	}
}

Reply via email to