diff --git a/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java b/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java index e2553d0fd3..493f164b63 100644 --- a/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java +++ b/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java @@ -160,11 +160,11 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO private EntityLookupCache, Serializable> aspectsCache; /** * Cache for the Node properties:
- * KEY: ID
+ * KEY: NodeVersionKey
* VALUE: Map<QName, Serializable>
* VALUE KEY: None
*/ - private EntityLookupCache, Serializable> propertiesCache; + private EntityLookupCache, Serializable> propertiesCache; /** * Cache for the Node parent assocs:
* KEY: ID
@@ -185,7 +185,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO rootNodesCache = new EntityLookupCache(new RootNodesCacheCallbackDAO()); nodesCache = new EntityLookupCache(new NodesCacheCallbackDAO()); aspectsCache = new EntityLookupCache, Serializable>(new AspectsCallbackDAO()); - propertiesCache = new EntityLookupCache, Serializable>(new PropertiesCallbackDAO()); + propertiesCache = new EntityLookupCache, Serializable>(new PropertiesCallbackDAO()); parentAssocsCache = new EntityLookupCache(new ParentAssocsCallbackDAO()); } @@ -327,7 +327,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO */ public void setPropertiesCache(SimpleCache> propertiesCache) { - this.propertiesCache = new EntityLookupCache, Serializable>( + this.propertiesCache = new EntityLookupCache, Serializable>( propertiesCache, CACHE_REGION_PROPERTIES, new PropertiesCallbackDAO()); @@ -527,10 +527,20 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO */ private void invalidateNodeCaches(Long nodeId) { - invalidateCachesByNodeId(null, nodeId, nodesCache); - invalidateCachesByNodeId(null, nodeId, propertiesCache); - invalidateCachesByNodeId(null, nodeId, aspectsCache); - invalidateCachesByNodeId(null, nodeId, parentAssocsCache); + // Take the current value from the nodesCache and use that to invalidate the other caches + Pair nodePair = nodesCache.getByKey(nodeId); + if (nodePair != null) + { + NodeVersionKey nodeVersionKey = nodePair.getSecond().getNodeVersionKey(); + // Properties + propertiesCache.removeByKey(nodeVersionKey); + // Aspects + aspectsCache.removeByKey(nodeId); + // Parent Assocs + parentAssocsCache.removeByKey(nodeId); + } + // Finally remove the node reference + nodesCache.removeByKey(nodeId); } /* @@ -1631,16 +1641,13 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO allRootNodesCache.remove(node.getNodePair().getSecond().getStoreRef()); } - // Remove value from the cache - nodesCache.removeByKey(nodeId); - // Remove aspects deleteNodeAspects(nodeId, null); - aspectsCache.removeByKey(nodeId); + setNodeAspectsCached(nodeId, Collections.emptySet()); // Remove properties deleteNodeProperties(nodeId, (Set) null); - propertiesCache.removeByKey(nodeId); + setNodePropertiesCached(nodeId, Collections.emptyMap()); // Remove associations invalidateCachesByNodeId(nodeId, nodeId, parentAssocsCache); @@ -1659,6 +1666,9 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO throw new ConcurrencyFailureException("Failed to update node: " + nodeUpdate); } + // Remove value from the cache + nodesCache.removeByKey(nodeId); + // Remove ACLs if (aclId != null) { @@ -1938,8 +1948,8 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO } catch (Throwable e) { - // Don't trust the properties cache for the node - propertiesCache.removeByKey(nodeId); + // Don't trust the caches for the node + invalidateNodeCaches(nodeId); // Focused error throw new AlfrescoRuntimeException( "Failed to write property deltas: \n" + @@ -2097,7 +2107,8 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO */ private Map getNodePropertiesCached(Long nodeId) { - Pair> cacheEntry = propertiesCache.getByKey(nodeId); + NodeVersionKey nodeVersionKey = getNodeNotNull(nodeId).getNodeVersionKey(); + Pair> cacheEntry = propertiesCache.getByKey(nodeVersionKey); if (cacheEntry == null) { throw new DataIntegrityViolationException("Invalid node ID: " + nodeId); @@ -2117,8 +2128,9 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO */ private void setNodePropertiesCached(Long nodeId, Map properties) { + NodeVersionKey nodeVersionKey = getNodeNotNull(nodeId).getNodeVersionKey(); properties = copyPropertiesAgainstModification(properties); - propertiesCache.setValue(nodeId, Collections.unmodifiableMap(properties)); + propertiesCache.setValue(nodeVersionKey, Collections.unmodifiableMap(properties)); } /** @@ -2147,16 +2159,16 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO * @author Derek Hulley * @since 3.4 */ - private class PropertiesCallbackDAO extends EntityLookupCallbackDAOAdaptor, Serializable> + private class PropertiesCallbackDAO extends EntityLookupCallbackDAOAdaptor, Serializable> { - public Pair> createValue(Map value) + public Pair> createValue(Map value) { throw new UnsupportedOperationException("A node always has a 'map' of properties."); } - public Pair> findByKey(Long nodeId) + public Pair> findByKey(NodeVersionKey nodeVersionKey) { - NodeVersionKey nodeVersionKey = getNodeNotNull(nodeId).getNodeVersionKey(); + Long nodeId = nodeVersionKey.getNodeId(); Map> propsRawByNodeVersionKey = selectNodeProperties(nodeId); // Check the node Txn ID for mismatch Map propsRaw = propsRawByNodeVersionKey.get(nodeVersionKey); @@ -2180,7 +2192,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO // Convert to public properties Map props = nodePropertyHelper.convertToPublicProperties(propsRaw); // Done - return new Pair>(nodeId, Collections.unmodifiableMap(props)); + return new Pair>(nodeVersionKey, Collections.unmodifiableMap(props)); } } @@ -3666,7 +3678,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO Long nodeId = node.getId(); NodeVersionKey nodeVersionKey = node.getNodeVersionKey(); nodesCache.setValue(nodeId, node); - if (propertiesCache.getValue(nodeId) == null) + if (propertiesCache.getValue(nodeVersionKey) == null) { propertiesNodeIds.add(nodeId); }