I have tested some removeNode situations and ran sometimes in a
ItemNotFoundException(../lockIsDeep).
I have created a node and adds a non-session scoped lock to it in the first
transaction.
After that i tried to add the lockToken and remove the node in a second
transaction.
This works fine if i wait about 30 seconds between the two operations. Now i
was a little bit
confused till i found the problem. First its the GarabageCollector intervall
that brings me to confusion.
Just for your information the two Transactions using the same Session
(JCASessionHandle) so its always the same ItemManager.
In the internalRemove Method of the ItemImpl the removeChildNode will be called.
The NodeImpl of the ChildNodeEntry will be received through the
ItemManager.getNode and
it receives the NodeData from its itemCache. If the NodeData will be found in
the itemCache its NodeState holds the PropertyNames
with the lockIsDeep PropertyName. If it is not found in the itemCache it will
created new and its state will be read new
from the ItemStateManager. The ItemData will be garbage collected from the
itemCache because its a weak reference.
In the onRemove Method of the NodeImpl the PropertyNames will be removed and
now i get a ItemNotFoundException from the
ItemManager that could not create a PropertyState. I think it could not create
it because the lock was previously removed.
With the appended TestCase you may understand me a little bit better ...
Maybe somebody who knows more about ItemStates can give me a hint where i
should handle this problem.
Help is welcome :-)
greets
claus
The TestCase:
public void testAddLockTokenRemoveNode2() throws Exception {
// create new node and lock it
UserTransaction utx = new UserTransactionImpl(superuser);
utx.begin();
// add node that is both lockable and referenceable, save
Node rootNode = superuser.getRootNode();
Node n = rootNode.addNode(nodeName1);
n.addMixin(mixLockable);
n.addMixin(mixReferenceable);
rootNode.save();
String uuid = n.getUUID();
// lock this new node
Lock lock = n.lock(true, false);
String lockToken = lock.getLockToken();
// commit
utx.commit();
// refresh Lock Info
lock = n.getLock();
// start new Transaction and try to add lock token unlock the node and
then remove it
utx = new UserTransactionImpl(superuser);
utx.begin();
Node otherNode = superuser.getNodeByUUID(uuid);
assertTrue("Node not locked", otherNode.isLocked());
// add lock token
superuser.addLockToken(lockToken);
// refresh Lock Info
lock = otherNode.getLock();
// assert: session must hold lock token
assertTrue("session must hold lock token", containsLockToken(superuser,
lockToken));
otherNode.unlock();
assertFalse("Node is locked", otherNode.isLocked());
otherNode.remove();
superuser.save();
utx.commit();
}