You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by KÖLL Claus <C....@TIROL.GV.AT> on 2009/09/30 13:25:05 UTC

Need help with ItemManager

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