From a667dc498a225d05699451062da263575c10f6ac Mon Sep 17 00:00:00 2001 From: Steven Glover Date: Thu, 3 Nov 2011 09:44:36 +0000 Subject: [PATCH] Fix for ALF-10842 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@31673 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repo/domain/node/AbstractNodeDAOImpl.java | 29 +++++++++++++--- .../alfresco/repo/node/NodeServiceTest.java | 33 ++++++++++++++++++- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java b/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java index 9757421b31..25119254cb 100644 --- a/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java +++ b/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java @@ -1495,6 +1495,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO invalidateNodePropertiesCache, invalidateParentAssocsCache); } + return updatedNode; } @@ -2337,12 +2338,17 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO Set newAspectQNames = new HashSet(existingAspectQNames); newAspectQNames.addAll(aspectQNamesToAdd); setNodeAspectsCached(nodeId, newAspectQNames); - + if (aspectQNamesToAdd.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 nodePair = getNodePair(nodeId); + StoreRef storeRef = nodePair.getSecond().getStoreRef(); + allRootNodesCache.remove(storeRef); } else { @@ -2384,14 +2390,29 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO { return false; } - + // Manually update the cache Set newAspectQNames = new HashSet(existingAspectQNames); newAspectQNames.removeAll(aspectQNames); setNodeAspectsCached(nodeId, newAspectQNames); - // Touch the node; all caches are fine - touchNode(nodeId, null, false, false, false); + // If we are removing the sys:aspect_root, then the parent assocs cache is unreliable + 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 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 return deleteCount > 0; diff --git a/source/java/org/alfresco/repo/node/NodeServiceTest.java b/source/java/org/alfresco/repo/node/NodeServiceTest.java index 75aa615128..d927b4619e 100644 --- a/source/java/org/alfresco/repo/node/NodeServiceTest.java +++ b/source/java/org/alfresco/repo/node/NodeServiceTest.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; 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.Status; 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.namespace.NamespaceService; import org.alfresco.service.namespace.QName; @@ -229,7 +231,36 @@ public class NodeServiceTest extends TestCase }; 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 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 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. * This is not a concurren thread issue; instead we delete a hierarchy and hold the txn