From 0d3580b1c8f62299fbcaa18c2e00b56a179c93ee Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Sat, 21 Sep 2013 16:07:46 +0000 Subject: [PATCH] Merged HEAD-BUG-FIX to HEAD (4.2) 55488: MNT-9648: Merged V4.1-BUG-FIX (4.1.7) to HEAD-BUG-FIX (4.2) 55001: Merged DEV to BRANCHES/DEV/V4.1-BUG-FIX: 54951: Test to reproduce MNT-9580: Daisy chained cm:original associations are cascade-deleted when the first original is deleted 54952: Fix MNT-9580: Daisy chained cm:original associations are cascade-deleted when the first original is deleted When an aspect is removed, the associations defined on the aspect were also being removed. However, the *inbound* associations instances were also being removed; in effect the behaviour of aspects on other nodes was being activated, which is incorrect. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@55793 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repo/node/db/DbNodeServiceImpl.java | 21 ++----- .../repo/copy/CopyServiceImplTest.java | 62 +++++++++++++++++++ 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java index e3a6d02587..323c259218 100644 --- a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java @@ -966,22 +966,11 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl nodeAssocIdsToRemove.add(assocPair.getFirst()); assocRefsRemoved.add(assocPair.getSecond()); } - Collection> sourceAssocRefs = nodeDAO.getSourceNodeAssocs(nodeId, assocTypeQName); - for (Pair assocPair : sourceAssocRefs) - { - if (isPendingDelete(assocPair.getSecond().getSourceRef())) - { - if (logger.isTraceEnabled()) - { - logger.trace( - "Aspect-triggered association removal: " + - "Ignoring peer associations where one of the nodes is pending delete: " + assocPair); - } - continue; - } - nodeAssocIdsToRemove.add(assocPair.getFirst()); - assocRefsRemoved.add(assocPair.getSecond()); - } + // MNT-9580: Daisy chained cm:original associations are cascade-deleted when the first original is deleted + // As a side-effect of the investigation of MNT-9446, it was dicovered that inbound associations (ones pointing *to* this aspect) + // were also being removed. This is incorrect because the aspect being removed here has no say over who points at it. + // Therefore, do not remove inbound associations because we only define outbound associations on types and aspects. + // Integrity checking will ensure that the correct behaviours are in place to maintain model integrity. } // Now delete peer associations int assocsDeleted = nodeDAO.removeNodeAssocs(nodeAssocIdsToRemove); diff --git a/source/test-java/org/alfresco/repo/copy/CopyServiceImplTest.java b/source/test-java/org/alfresco/repo/copy/CopyServiceImplTest.java index 2c77d1d686..7b082f9c8f 100644 --- a/source/test-java/org/alfresco/repo/copy/CopyServiceImplTest.java +++ b/source/test-java/org/alfresco/repo/copy/CopyServiceImplTest.java @@ -634,6 +634,68 @@ public class CopyServiceImplTest extends TestCase assertFalse("Copy should not have cm:copiedfrom aspect. ", nodeService.hasAspect(firstCopy, ContentModel.ASPECT_COPIEDFROM)); } + /** + * + * MNT-9580: Daisy chained cm:original associations are cascade-deleted when the first original is deleted + * + */ + public void testCopyOfCopyOfCopy() + { + IntegrityChecker integrityChecker = (IntegrityChecker) ctx.getBean("integrityChecker"); + + // Create the node used for copying + ChildAssociationRef childAssocRef = nodeService.createNode( + rootNodeRef, + ContentModel.ASSOC_CHILDREN, + QName.createQName("{test}test"), + TEST_TYPE_QNAME, + createTypePropertyBag()); + NodeRef nodeRef = childAssocRef.getChildRef(); + + PagingRequest pageRequest = new PagingRequest(10); + pageRequest.setRequestTotalCountMax(200); + PagingResults copies = null; + + NodeRef currentOriginal = nodeRef; + NodeRef copyNodeRef = null; + + for (int i = 1; i <= 5; i++) + { + copyNodeRef = copyService.copy( + currentOriginal, + rootNodeRef, + ContentModel.ASSOC_CHILDREN, + QName.createQName("{test}copyAssoc"+i)); + copies = copyService.getCopies(currentOriginal, pageRequest); + assertEquals("Incorrect number of copies on iteration " + i, 1, copies.getPage().size()); + + // Check that the original node can be retrieved + NodeRef originalCheck = copyService.getOriginal(copyNodeRef); + assertEquals("Original is not as expected. ", currentOriginal, originalCheck); + // Run integrity checks to ensure that commit has a chance + integrityChecker.checkIntegrity(); + + currentOriginal = copyNodeRef; + } + + // Now, delete the nodes starting with the first original + currentOriginal = nodeRef; + copyNodeRef = null; + for (int i = 1; i < 5; i++) + { + // Each node must be an original + copies = copyService.getCopies(currentOriginal, pageRequest); + assertEquals("Incorrect number of copies on iteration " + i, 1, copies.getPage().size()); + copyNodeRef = copies.getPage().get(0).getNodeRef(); + // Delete current original + nodeService.deleteNode(currentOriginal); + // Run integrity checks to ensure that commit has a chance + integrityChecker.checkIntegrity(); + + currentOriginal = copyNodeRef; + } + } + /** * Test the behaviour of the aspect when copying types not derived from cm:object */