diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/patch-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/patch-common-SqlMap.xml
index 81d41e45fc..96a9b4604d 100644
--- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/patch-common-SqlMap.xml
+++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/patch-common-SqlMap.xml
@@ -302,8 +302,8 @@
update
alf_child_assoc
set
- qname_crc = ?,
- child_node_name_crc = ?
+ child_node_name_crc = ?,
+ qname_crc = ?
where
id = ?
diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties
index 3dda18682c..013c664e12 100644
--- a/config/alfresco/messages/patch-service.properties
+++ b/config/alfresco/messages/patch-service.properties
@@ -304,6 +304,8 @@ patch.fixNameCrcValues.description=Fixes name and qname CRC32 values to match UT
patch.fixNameCrcValues.result=Fixed CRC32 values for UTF-8 encoding for {0} node child associations. See file {1} for details.
patch.fixNameCrcValues.fixed=Updated CRC32 values for association ID {0}, name ''{1}'': {2} -> {3}, qname ''{4}'': {5} -> {6}.
patch.fixNameCrcValues.unableToChange=Failed to update the CRC32 value for association ID {0}: \n Node name: {1} \n name CRC old: {2} \n name CRC new: {3} \n qname: {4} \n qname CRC old: {5} \n qname CRC new: {6} \n Error: {7}
+patch.fixNameCrcValues.associationTypeNotDefined=Association type ''{0}'' has not been defined.
+patch.fixNameCrcValues.associationTypeNotChild=Association type ''{0}'' does not represent a child association but is used as one.
patch.personUsagePatch.description=Add person 'cm:sizeCurrent' property (if missing).
patch.personUsagePatch.result1=Added 'cm:sizeCurrent' property to {0} people that were missing this property.
diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml
index 597ac318e8..bc8a0da108 100644
--- a/config/alfresco/patch/patch-services-context.xml
+++ b/config/alfresco/patch/patch-services-context.xml
@@ -1965,6 +1965,9 @@
+
+
+
diff --git a/source/java/org/alfresco/repo/admin/patch/impl/FixNameCrcValuesPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/FixNameCrcValuesPatch.java
index bbc1395df5..6d3ac2f84a 100644
--- a/source/java/org/alfresco/repo/admin/patch/impl/FixNameCrcValuesPatch.java
+++ b/source/java/org/alfresco/repo/admin/patch/impl/FixNameCrcValuesPatch.java
@@ -29,6 +29,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
+import org.alfresco.error.StackTraceUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.admin.patch.PatchExecuter;
import org.alfresco.repo.batch.BatchProcessWorkProvider;
@@ -39,6 +40,7 @@ import org.alfresco.repo.domain.node.ChildAssocEntity;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
+import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryException;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.namespace.QName;
@@ -59,6 +61,8 @@ public class FixNameCrcValuesPatch extends AbstractPatch
private static final String MSG_SUCCESS = "patch.fixNameCrcValues.result";
private static final String MSG_REWRITTEN = "patch.fixNameCrcValues.fixed";
private static final String MSG_UNABLE_TO_CHANGE = "patch.fixNameCrcValues.unableToChange";
+ private static final String ERR_ASSOCIATION_TYPE_NOT_DEFINED = "patch.fixNameCrcValues.associationTypeNotDefined";
+ private static final String ERR_ASSOCIATION_TYPE_NOT_CHILD = "patch.fixNameCrcValues.associationTypeNotChild";
private PatchDAO patchDAO;
private QNameDAO qnameDAO;
@@ -107,6 +111,8 @@ public class FixNameCrcValuesPatch extends AbstractPatch
super.checkProperties();
checkPropertyNotNull(patchDAO, "patchDAO");
checkPropertyNotNull(qnameDAO, "qnameDAO");
+ checkPropertyNotNull(controlDAO, "controlDAO");
+ checkPropertyNotNull(dictionaryService, "dictionaryService");
checkPropertyNotNull(applicationEventPublisher, "applicationEventPublisher");
}
@@ -236,11 +242,29 @@ public class FixNameCrcValuesPatch extends AbstractPatch
ChildAssocEntity entity = new ChildAssocEntity();
entity.setChildNodeNameAll(dictionaryService, typeQName, childNodeName);
entity.setQNameAll(qnameDAO, qname, false);
- // Check the CRC values for cm:name
- if (entity.getChildNodeNameCrc().equals(childNodeNameCrc))
+ Long childNodeNameCrcNew = entity.getChildNodeNameCrc();
+ Long qnameCrcNew = entity.getQnameCrc();
+ entity = null; // Just checking that we don't misuse it
+
+ AssociationDefinition assocDef = dictionaryService.getAssociation(typeQName);
+ if (assocDef == null)
{
- // Check the CRC for the QName
- if (entity.getQnameCrc().equals(qnameCrc))
+ throw new DictionaryException(ERR_ASSOCIATION_TYPE_NOT_DEFINED, typeQName, assocId);
+ }
+ else if (!assocDef.isChild())
+ {
+ throw new DictionaryException(ERR_ASSOCIATION_TYPE_NOT_CHILD, typeQName, assocId);
+ }
+ ChildAssociationDefinition childAssocDef = (ChildAssociationDefinition) assocDef;
+ boolean requiresNameConstraint = !childAssocDef.getDuplicateChildNamesAllowed();
+
+ // Check the CRC for the QName
+ if (qnameCrcNew.equals(qnameCrc))
+ {
+ // Check the CRC values for cm:name
+ // - value might have stayed the same
+ // - Any existing name crc negative value is fine if the name constraint need not be enforced
+ if (childNodeNameCrcNew.equals(childNodeNameCrc) || (childNodeNameCrc < 0 && !requiresNameConstraint))
{
// This child assoc is good
return;
@@ -250,22 +274,16 @@ public class FixNameCrcValuesPatch extends AbstractPatch
Savepoint savepoint = null;
try
{
- AssociationDefinition assocDef = dictionaryService.getAssociation(typeQName);
- if (assocDef == null)
- {
- throw new DictionaryException("Association type not defined: " + typeQName);
- }
-
// Being here indicates that the association needs to be updated
savepoint = controlDAO.createSavepoint("FixNameCrcValuesPatch");
- patchDAO.updateChildAssocCrc(assocId, childNodeNameCrc, qnameCrc);
+ patchDAO.updateChildAssocCrc(assocId, childNodeNameCrcNew, qnameCrcNew);
controlDAO.releaseSavepoint(savepoint);
String msg = I18NUtil.getMessage(
MSG_REWRITTEN,
assocId,
- childNodeName, childNodeNameCrc, entity.getChildNodeNameCrc(),
- qname, qnameCrc, entity.getQnameCrc());
+ childNodeName, childNodeNameCrc, childNodeNameCrcNew,
+ qname, qnameCrc, qnameCrcNew);
writeLine(msg);
}
catch (Throwable e)
@@ -277,8 +295,8 @@ public class FixNameCrcValuesPatch extends AbstractPatch
String msg = I18NUtil.getMessage(
MSG_UNABLE_TO_CHANGE,
assocId,
- childNodeName, childNodeNameCrc, entity.getChildNodeNameCrc(),
- qname, qnameCrc, entity.getQnameCrc(),
+ childNodeName, childNodeNameCrc, childNodeNameCrcNew,
+ qname, qnameCrc, qnameCrcNew,
e.getMessage());
// We just log this and add details to the message file
if (logger.isDebugEnabled())
@@ -289,7 +307,9 @@ public class FixNameCrcValuesPatch extends AbstractPatch
{
logger.warn(msg);
}
- writeLine(msg);
+ StringBuilder sb = new StringBuilder(1024);
+ StackTraceUtil.buildStackTrace(msg, e.getStackTrace(), sb, 0);
+ writeLine(sb.toString());
}
}