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);
}
}
}