Fix for ALF-10842

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@31673 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Steven Glover
2011-11-03 09:44:36 +00:00
parent 5d0c32ca5a
commit a667dc498a
2 changed files with 57 additions and 5 deletions

View File

@@ -1495,6 +1495,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
invalidateNodePropertiesCache, invalidateNodePropertiesCache,
invalidateParentAssocsCache); invalidateParentAssocsCache);
} }
return updatedNode; return updatedNode;
} }
@@ -2337,12 +2338,17 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
Set<QName> newAspectQNames = new HashSet<QName>(existingAspectQNames); Set<QName> newAspectQNames = new HashSet<QName>(existingAspectQNames);
newAspectQNames.addAll(aspectQNamesToAdd); newAspectQNames.addAll(aspectQNamesToAdd);
setNodeAspectsCached(nodeId, newAspectQNames); setNodeAspectsCached(nodeId, newAspectQNames);
if (aspectQNamesToAdd.contains(ContentModel.ASPECT_ROOT)) if (aspectQNamesToAdd.contains(ContentModel.ASPECT_ROOT))
{ {
// This is a special case. The presence of the aspect affects the path // This is a special case. The presence of the aspect affects the path
// calculations, which are stored in the parent assocs cache // calculations, which are stored in the parent assocs cache
touchNode(nodeId, null, false, false, true); touchNode(nodeId, null, false, false, true);
// invalidate root nodes cache for the store
Pair<Long, NodeRef> nodePair = getNodePair(nodeId);
StoreRef storeRef = nodePair.getSecond().getStoreRef();
allRootNodesCache.remove(storeRef);
} }
else else
{ {
@@ -2384,14 +2390,29 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
{ {
return false; return false;
} }
// Manually update the cache // Manually update the cache
Set<QName> newAspectQNames = new HashSet<QName>(existingAspectQNames); Set<QName> newAspectQNames = new HashSet<QName>(existingAspectQNames);
newAspectQNames.removeAll(aspectQNames); newAspectQNames.removeAll(aspectQNames);
setNodeAspectsCached(nodeId, newAspectQNames); setNodeAspectsCached(nodeId, newAspectQNames);
// Touch the node; all caches are fine // If we are removing the sys:aspect_root, then the parent assocs cache is unreliable
touchNode(nodeId, null, false, false, false); if (aspectQNames.contains(ContentModel.ASPECT_ROOT))
{
// This is a special case. The presence of the aspect affects the path
// calculations, which are stored in the parent assocs cache
touchNode(nodeId, null, false, false, true);
// invalidate root nodes cache for the store
Pair<Long, NodeRef> nodePair = getNodePair(nodeId);
StoreRef storeRef = nodePair.getSecond().getStoreRef();
allRootNodesCache.remove(storeRef);
}
else
{
// Touch the node; all caches are fine
touchNode(nodeId, null, false, false, false);
}
// Done // Done
return deleteCount > 0; return deleteCount > 0;

View File

@@ -24,6 +24,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
import junit.framework.TestCase; import junit.framework.TestCase;
@@ -38,6 +39,7 @@ import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeRef.Status; import org.alfresco.service.cmr.repository.NodeRef.Status;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -229,7 +231,36 @@ public class NodeServiceTest extends TestCase
}; };
txnService.getRetryingTransactionHelper().doInTransaction(setupCallback); txnService.getRetryingTransactionHelper().doInTransaction(setupCallback);
} }
public void testRootAspect() throws Exception
{
final NodeRef workspaceRootNodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
final NodeRef[] nodes = new NodeRef[6];
buildNodeHierarchy(workspaceRootNodeRef, nodes);
Set<NodeRef> allRootNodes = nodeService.getAllRootNodes(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
int initialNumRootNodes = allRootNodes.size();
nodeService.addAspect(nodes[1], ContentModel.ASPECT_ROOT, null);
nodeService.addAspect(nodes[3], ContentModel.ASPECT_ROOT, null);
nodeService.addAspect(nodes[4], ContentModel.ASPECT_ROOT, null);
allRootNodes = nodeService.getAllRootNodes(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
assertEquals("", 3, allRootNodes.size() - initialNumRootNodes);
List<Path> paths = nodeService.getPaths(nodes[5], false);
assertEquals("", 4, paths.size());
nodeService.removeAspect(nodes[3], ContentModel.ASPECT_ROOT);
allRootNodes = nodeService.getAllRootNodes(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
assertEquals("", 2, allRootNodes.size() - initialNumRootNodes);
paths = nodeService.getPaths(nodes[5], false);
for(Path path : paths)
{
System.out.println("Path = " + path.toString());
}
assertEquals("", 3, paths.size());
}
/** /**
* Tests that two separate node trees can be deleted concurrently at the database level. * Tests that two separate node trees can be deleted concurrently at the database level.
* This is not a concurren thread issue; instead we delete a hierarchy and hold the txn * This is not a concurren thread issue; instead we delete a hierarchy and hold the txn