You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ap...@apache.org on 2018/05/16 04:07:51 UTC

[2/2] atlas git commit: ATLAS-2679: Update qualifiedName category hierarchy corresponding to any change to category

ATLAS-2679: Update qualifiedName category hierarchy corresponding to any change to category

Change-Id: I4cddcfe76eabcf7ee705b60848521158bb33a8a5


Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/66f8ae16
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/66f8ae16
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/66f8ae16

Branch: refs/heads/master
Commit: 66f8ae16045b79d8839ee2088fc5cc64ffa2fa5d
Parents: 801db28
Author: apoorvnaik <ap...@apache.org>
Authored: Thu May 10 16:09:12 2018 -0700
Committer: apoorvnaik <ap...@apache.org>
Committed: Tue May 15 21:07:26 2018 -0700

----------------------------------------------------------------------
 .../java/org/apache/atlas/AtlasErrorCode.java   |   3 +-
 .../atlas/model/glossary/AtlasGlossary.java     |   7 +-
 .../model/glossary/AtlasGlossaryBaseObject.java |  14 +-
 .../model/glossary/AtlasGlossaryCategory.java   |   6 -
 .../atlas/model/glossary/AtlasGlossaryTerm.java |   2 -
 .../atlas/glossary/GlossaryCategoryUtils.java   | 293 +++++++++++++------
 .../apache/atlas/glossary/GlossaryService.java  | 184 ++++++------
 .../atlas/glossary/GlossaryTermUtils.java       | 108 ++++---
 .../apache/atlas/glossary/GlossaryUtils.java    |  23 ++
 .../atlas/glossary/GlossaryServiceTest.java     | 129 +++++++-
 .../org/apache/atlas/web/rest/GlossaryREST.java |   2 +-
 11 files changed, 522 insertions(+), 249 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/atlas/blob/66f8ae16/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 7cf3fd1..3a60978 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -26,6 +26,7 @@ import java.util.Arrays;
 
 public enum AtlasErrorCode {
     NO_SEARCH_RESULTS(204, "ATLAS-204-00-001", "Given search filter {0} did not yield any results"),
+    DATA_ACCESS_SAVE_FAILED(204, "ATLAS-204-00-002", "Save failed: {0} has no updates"),
 
     UNKNOWN_TYPE(400, "ATLAS-400-00-001", "Unknown type {0} for {1}.{2}"),
     CIRCULAR_REFERENCE(400, "ATLAS-400-00-002", "{0}: invalid supertypes - circular reference back to self {1}"),
@@ -144,6 +145,7 @@ public enum AtlasErrorCode {
     INVALID_CHILD_CATEGORY_DIFFERENT_GLOSSARY(400, "ATLAS-400-00-07F", "Invalid child category relationship: Child category (guid = {0}) belongs to different glossary"),
     INVALID_TERM_DISSOCIATION(400, "ATLAS-400-00-080", "Given term (guid={0}) is not associated to entity(guid={1})"),
     ATTRIBUTE_TYPE_INVALID(400, "ATLAS-400-00-081", "{0}.{1}: invalid attribute type. Attribute cannot be of type classification"),
+    MISSING_CATEGORY_DISPLAY_NAME(400, "ATLAS-400-00-082", "Category displayName is empty/null"),
 
     UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"),
 
@@ -196,7 +198,6 @@ public enum AtlasErrorCode {
     SQOOP_HOOK(500, "ATLAS-500-00-00F", "SqoopHook: {0}"),
     HIVE_HOOK(500, "ATLAS-500-00-010", "HiveHook: {0}"),
     HIVE_HOOK_METASTORE_BRIDGE(500, "ATLAS-500-00-011", "HiveHookMetaStoreBridge: {0}"),
-    DATA_ACCESS_SAVE_FAILED(500, "ATLAS-500-00-012", "Save failed: {0}"),
     DATA_ACCESS_LOAD_FAILED(500, "ATLAS-500-00-013", "Load failed: {0}"),
     ENTITY_NOTIFICATION_FAILED(500, "ATLAS-500-00-014", "Notification failed for operation: {0} : {1}");
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/66f8ae16/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
index b99817c..ccd0b90 100644
--- a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
+++ b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
@@ -146,12 +146,10 @@ public class AtlasGlossary extends AtlasGlossaryBaseObject {
 
     @Override
     protected StringBuilder toString(final StringBuilder sb) {
-        sb.append("{");
-        sb.append("language='").append(language).append('\'');
+        sb.append(", language='").append(language).append('\'');
         sb.append(", usage='").append(usage).append('\'');
         sb.append(", terms=").append(terms);
         sb.append(", categories=").append(categories);
-        sb.append('}');
 
         return sb;
     }
@@ -234,11 +232,8 @@ public class AtlasGlossary extends AtlasGlossaryBaseObject {
 
         @Override
         public StringBuilder toString(StringBuilder sb) {
-            sb.append("{");
-            super.toString(sb);
             sb.append(", termInfo=").append(termInfo);
             sb.append(", categoryInfo=").append(categoryInfo);
-            sb.append('}');
 
             return sb;
         }

http://git-wip-us.apache.org/repos/asf/atlas/blob/66f8ae16/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
index 556362f..959d347 100644
--- a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
+++ b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
@@ -29,13 +29,13 @@ import java.util.Objects;
 public abstract class AtlasGlossaryBaseObject extends AtlasBaseModelObject {
 
     // Core attributes
-    protected      String     displayName;
-    protected      String     shortDescription;
-    protected      String     longDescription;
+    private   String qualifiedName;
+    protected String displayName;
+    protected String shortDescription;
+    protected String longDescription;
 
     // Classifications
     protected List<AtlasClassification> classifications;
-    private   String                    qualifiedName;
 
     public AtlasGlossaryBaseObject() {
     }
@@ -129,13 +129,11 @@ public abstract class AtlasGlossaryBaseObject extends AtlasBaseModelObject {
 
     @Override
     protected StringBuilder toString(final StringBuilder sb) {
-        sb.append("{");
-        sb.append("displayName='").append(displayName).append('\'');
+        sb.append(", qualifiedName='").append(qualifiedName).append('\'');
+        sb.append(", displayName='").append(displayName).append('\'');
         sb.append(", shortDescription='").append(shortDescription).append('\'');
         sb.append(", longDescription='").append(longDescription).append('\'');
         sb.append(", classifications=").append(classifications);
-        sb.append(", qualifiedName='").append(qualifiedName).append('\'');
-        sb.append('}');
 
         return sb;
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/66f8ae16/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
index 043eaa5..9fcca5d 100644
--- a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
+++ b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
@@ -138,16 +138,10 @@ public class AtlasGlossaryCategory extends AtlasGlossaryBaseObject {
 
     @Override
     protected StringBuilder toString(final StringBuilder sb) {
-        sb.append("{");
-        sb.append("displayName='").append(getDisplayName()).append('\'');
-        sb.append(", shortDescription='").append(getShortDescription()).append('\'');
-        sb.append(", longDescription='").append(getLongDescription()).append('\'');
         sb.append(", anchor=").append(anchor);
         sb.append(", parentCategory=").append(parentCategory);
         sb.append(", childrenCategories=").append(childrenCategories);
         sb.append(", terms=").append(terms);
-        sb.append(", classifications=").append(getClassifications());
-        sb.append('}');
 
         return sb;
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/66f8ae16/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java
index 7b4543b..daf6c7b 100644
--- a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java
+++ b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java
@@ -376,7 +376,6 @@ public class AtlasGlossaryTerm extends AtlasGlossaryBaseObject {
 
     @Override
     protected StringBuilder toString(final StringBuilder sb) {
-        sb.append("{");
         sb.append("examples=").append(examples);
         sb.append(", abbreviation='").append(abbreviation).append('\'');
         sb.append(", usage='").append(usage).append('\'');
@@ -396,7 +395,6 @@ public class AtlasGlossaryTerm extends AtlasGlossaryBaseObject {
         sb.append(", classifies=").append(classifies);
         sb.append(", validValues=").append(validValues);
         sb.append(", validValuesFor=").append(validValuesFor);
-        sb.append('}');
 
         return sb;
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/66f8ae16/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java b/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java
index e1b30c4..42cdef8 100644
--- a/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java
+++ b/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java
@@ -19,7 +19,9 @@ package org.apache.atlas.glossary;
 
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.glossary.AtlasGlossary;
 import org.apache.atlas.model.glossary.AtlasGlossaryCategory;
+import org.apache.atlas.model.glossary.relations.AtlasGlossaryHeader;
 import org.apache.atlas.model.glossary.relations.AtlasRelatedCategoryHeader;
 import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader;
 import org.apache.atlas.model.instance.AtlasObjectId;
@@ -51,68 +53,103 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         super(relationshipStore, typeRegistry, dataAccess);
     }
 
-    public void processCategoryRelations(AtlasGlossaryCategory updatedCategory, AtlasGlossaryCategory existing, RelationshipOperation op) throws AtlasBaseException {
+    public Map<String, AtlasGlossaryCategory> processCategoryRelations(AtlasGlossaryCategory storeObject, AtlasGlossaryCategory updatedCategory, RelationshipOperation op) throws AtlasBaseException {
         if (DEBUG_ENABLED) {
-            LOG.debug("==> GlossaryCategoryUtils.processCategoryRelations({}, {}, {})", updatedCategory, existing, op);
+            LOG.debug("==> GlossaryCategoryUtils.processCategoryRelations({}, {}, {})", storeObject, updatedCategory, op);
         }
-        processCategoryAnchor(updatedCategory, existing, op);
-        processParentCategory(updatedCategory, existing, op);
-        processCategoryChildren(updatedCategory, existing, op);
-        processAssociatedTerms(updatedCategory, existing, op);
+        Map<String, AtlasGlossaryCategory> impactedCategories = new HashMap<>();
+
+        processCategoryAnchor(storeObject, updatedCategory, op, impactedCategories);
+        processParentCategory(storeObject, updatedCategory, op, impactedCategories);
+        processCategoryChildren(storeObject, updatedCategory, op, impactedCategories);
+        processAssociatedTerms(storeObject, updatedCategory, op);
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryCategoryUtils.processCategoryRelations()");
+            LOG.debug("<== GlossaryCategoryUtils.processCategoryRelations(): {}", impactedCategories);
         }
+
+        return impactedCategories;
     }
 
-    private void processCategoryAnchor(AtlasGlossaryCategory updatedCategory, AtlasGlossaryCategory existing, RelationshipOperation op) throws AtlasBaseException {
+    private void processCategoryAnchor(AtlasGlossaryCategory storeObject, AtlasGlossaryCategory updatedCategory,
+                                       RelationshipOperation op, Map<String, AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
         if (Objects.isNull(updatedCategory.getAnchor()) && op != RelationshipOperation.DELETE) {
             throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR);
         }
 
+        AtlasGlossaryHeader existingAnchor        = storeObject.getAnchor();
+        AtlasGlossaryHeader updatedCategoryAnchor = updatedCategory.getAnchor();
+
         switch (op) {
             case CREATE:
-                if (DEBUG_ENABLED) {
-                    LOG.debug("Creating new category anchor, category = {}, glossary = {}", existing.getGuid(), updatedCategory.getAnchor().getDisplayText());
+                if (StringUtils.isEmpty(updatedCategoryAnchor.getGlossaryGuid())) {
+                    throw new AtlasBaseException(AtlasErrorCode.INVALID_NEW_ANCHOR_GUID);
+                } else {
+                    if (DEBUG_ENABLED) {
+                        LOG.debug("Creating new category anchor, category = {}, glossary = {}", storeObject.getGuid(), updatedCategory.getAnchor().getGlossaryGuid());
+                    }
+
+                    // Derive the qualifiedName
+                    String anchorGlossaryGuid = updatedCategory.getAnchor().getGlossaryGuid();
+                    AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+                    storeObject.setQualifiedName(storeObject.getDisplayName()+ "@" + glossary.getQualifiedName());
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Derived qualifiedName = {}", storeObject.getQualifiedName());
+                    }
+
+                    createRelationship(defineCategoryAnchorRelation(anchorGlossaryGuid, storeObject.getGuid()));
                 }
-                String anchorGlossaryGuid = updatedCategory.getAnchor().getGlossaryGuid();
-                createRelationship(defineCategoryAnchorRelation(anchorGlossaryGuid, existing.getGuid()));
                 break;
             case UPDATE:
-                if (!Objects.equals(updatedCategory.getAnchor(), existing.getAnchor())) {
+                if (!Objects.equals(existingAnchor, updatedCategoryAnchor)) {
                     if (Objects.isNull(updatedCategory.getAnchor().getGlossaryGuid())) {
                         throw new AtlasBaseException(AtlasErrorCode.INVALID_NEW_ANCHOR_GUID);
                     }
 
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Updating category anchor, category = {}, currAnchor = {}, newAnchor = {}", existing.getGuid(),
-                                  existing.getAnchor().getDisplayText(), updatedCategory.getAnchor().getDisplayText());
+                        LOG.debug("Updating category anchor, currAnchor = {}, newAnchor = {} and category = {}",
+                                  storeObject.getAnchor().getGlossaryGuid(),
+                                  updatedCategory.getAnchor().getGlossaryGuid(),
+                                  storeObject.getGuid());
+                    }
+                    relationshipStore.deleteById(storeObject.getAnchor().getRelationGuid());
+
+                    // Derive the qualifiedName when anchor changes
+                    String        anchorGlossaryGuid = updatedCategory.getAnchor().getGlossaryGuid();
+                    AtlasGlossary glossary           = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+                    storeObject.setQualifiedName(storeObject.getDisplayName()+ "@" + glossary.getQualifiedName());
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Derived qualifiedName = {}", storeObject.getQualifiedName());
                     }
-                    relationshipStore.deleteById(existing.getAnchor().getRelationGuid());
-                    createRelationship(defineCategoryAnchorRelation(updatedCategory.getAnchor().getGlossaryGuid(), existing.getGuid()));
+
+                    createRelationship(defineCategoryAnchorRelation(updatedCategory.getAnchor().getGlossaryGuid(), storeObject.getGuid()));
+
+                    // Anchor changed, qualifiedName of children needs an update
+                    updateChildCategories(storeObject, storeObject.getChildrenCategories(), impactedCategories, false);
                 }
                 break;
             case DELETE:
-                if (Objects.nonNull(existing.getAnchor())) {
+                if (Objects.nonNull(storeObject.getAnchor())) {
                     if (DEBUG_ENABLED) {
                         LOG.debug("Deleting category anchor");
                     }
-                    relationshipStore.deleteById(existing.getAnchor().getRelationGuid());
+                    relationshipStore.deleteById(storeObject.getAnchor().getRelationGuid());
                 }
                 break;
         }
     }
 
-    private void processParentCategory(AtlasGlossaryCategory updatedCategory, AtlasGlossaryCategory existing, RelationshipOperation op) throws AtlasBaseException {
+    private void processParentCategory(AtlasGlossaryCategory storeObject, AtlasGlossaryCategory updatedCategory,
+                                       RelationshipOperation op, Map<String, AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
         AtlasRelatedCategoryHeader newParent      = updatedCategory.getParentCategory();
-        AtlasRelatedCategoryHeader existingParent = existing.getParentCategory();
+        AtlasRelatedCategoryHeader existingParent = storeObject.getParentCategory();
+
         switch (op) {
             case CREATE:
                 if (Objects.nonNull(newParent)) {
-                    if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new parent, category = {}, parent = {}", existing.getGuid(), newParent.getDisplayText());
-                    }
-                    createRelationship(defineCategoryHierarchyLink(newParent, existing.getGuid()));
+                    processNewParent(storeObject, newParent, impactedCategories);
                 }
                 break;
             case UPDATE:
@@ -124,18 +161,12 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                 }
 
                 if (Objects.isNull(existingParent)) {
-                    if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new parent, category = {}, parent = {}", existing.getGuid(), newParent.getDisplayText());
-                    }
-                    createRelationship(defineCategoryHierarchyLink(newParent, existing.getGuid()));
+                    processNewParent(storeObject, newParent, impactedCategories);
                 } else if (Objects.isNull(newParent)) {
-                    if (DEBUG_ENABLED) {
-                        LOG.debug("Removing category parent, category = {}, parent = {}", existing.getGuid(), existingParent.getDisplayText());
-                    }
-                    relationshipStore.deleteById(existingParent.getRelationGuid());
+                    processParentRemoval(storeObject, updatedCategory, existingParent, impactedCategories);
                 } else {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Updating category parent, category = {}, currParent = {}, newParent = {}", existing.getGuid(), existingParent.getDisplayText(), newParent.getDisplayText());
+                        LOG.debug("Updating category parent, category = {}, currParent = {}, newParent = {}", storeObject.getGuid(), existingParent.getDisplayText(), newParent.getDisplayText());
                     }
                     AtlasRelationship parentRelationship = relationshipStore.getById(existingParent.getRelationGuid());
                     if (existingParent.getCategoryGuid().equals(newParent.getCategoryGuid())) {
@@ -144,48 +175,83 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                     } else {
                         // Delete link to existing parent and link to new parent
                         relationshipStore.deleteById(parentRelationship.getGuid());
-                        createRelationship(defineCategoryHierarchyLink(newParent, existing.getGuid()));
+                        createRelationship(defineCategoryHierarchyLink(newParent, storeObject.getGuid()));
                     }
                 }
                 break;
             case DELETE:
                 if (Objects.nonNull(existingParent)) {
-                    if (DEBUG_ENABLED) {
-                        LOG.debug("Removing category parent, category = {}, parent = {}", existing.getGuid(), existingParent.getDisplayText());
-                    }
-                    relationshipStore.deleteById(existingParent.getRelationGuid());
+                    processParentRemoval(storeObject, updatedCategory, existingParent, impactedCategories);
                 }
                 break;
         }
     }
 
-    private void processAssociatedTerms(AtlasGlossaryCategory updatedCategory, AtlasGlossaryCategory existing, RelationshipOperation op) throws AtlasBaseException {
+    private void processNewParent(AtlasGlossaryCategory storeObject, AtlasRelatedCategoryHeader newParent, Map<String, AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
+        if (DEBUG_ENABLED) {
+            LOG.debug("Creating new parent, category = {}, parent = {}", storeObject.getGuid(), newParent.getDisplayText());
+        }
+        createRelationship(defineCategoryHierarchyLink(newParent, storeObject.getGuid()));
+
+        // New parent added, qualifiedName needs recomputation
+        // Derive the qualifiedName of the Glossary
+        AtlasGlossaryCategory parentCategory = dataAccess.load(getAtlasGlossaryCategorySkeleton(newParent.getCategoryGuid()));
+        storeObject.setQualifiedName(storeObject.getDisplayName() + "." + parentCategory.getQualifiedName());
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Derived qualifiedName = {}", storeObject.getQualifiedName());
+        }
+
+        updateChildCategories(storeObject, storeObject.getChildrenCategories(), impactedCategories, false);
+    }
+
+    private void processParentRemoval(AtlasGlossaryCategory storeObject, AtlasGlossaryCategory updatedCategory, AtlasRelatedCategoryHeader existingParent, Map<String, AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
+        if (DEBUG_ENABLED) {
+            LOG.debug("Removing category parent, category = {}, parent = {}", storeObject.getGuid(), existingParent.getDisplayText());
+        }
+        relationshipStore.deleteById(existingParent.getRelationGuid());
+
+        // Parent deleted, qualifiedName needs recomputation
+
+        // Derive the qualifiedName of the Glossary
+        String        anchorGlossaryGuid = updatedCategory.getAnchor().getGlossaryGuid();
+        AtlasGlossary glossary           = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+        storeObject.setQualifiedName(storeObject.getDisplayName() + "@" + glossary.getQualifiedName());
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Derived qualifiedName = {}", storeObject.getQualifiedName());
+        }
+
+        updateChildCategories(storeObject, storeObject.getChildrenCategories(), impactedCategories, false);
+    }
+
+    private void processAssociatedTerms(AtlasGlossaryCategory storeObject, AtlasGlossaryCategory updatedCategory, RelationshipOperation op) throws AtlasBaseException {
         Map<String, AtlasRelatedTermHeader> newTerms      = getTerms(updatedCategory);
-        Map<String, AtlasRelatedTermHeader> existingTerms = getTerms(existing);
+        Map<String, AtlasRelatedTermHeader> existingTerms = getTerms(storeObject);
 
         switch (op) {
             case CREATE:
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Creating term relation with category = {}, terms = {}", existing.getDisplayName(),
+                    LOG.debug("Creating term relation with category = {}, terms = {}", storeObject.getDisplayName(),
                               Objects.nonNull(newTerms) ? newTerms.size() : "none");
                 }
-                createTermCategorizationRelationships(existing, newTerms.values());
+                createTermCategorizationRelationships(storeObject, newTerms.values());
                 break;
             case UPDATE:
                 if (MapUtils.isEmpty(existingTerms)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating term relation with category = {}, terms = {}", existing.getDisplayName(),
+                        LOG.debug("Creating term relation with category = {}, terms = {}", storeObject.getDisplayName(),
                                   Objects.nonNull(newTerms) ? newTerms.size() : "none");
                     }
-                    createTermCategorizationRelationships(existing, newTerms.values());
+                    createTermCategorizationRelationships(storeObject, newTerms.values());
                     break;
                 }
 
                 if (MapUtils.isEmpty(newTerms)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Deleting term relation with category = {}, terms = {}", existing.getDisplayName(), existingTerms.size());
+                        LOG.debug("Deleting term relation with category = {}, terms = {}", storeObject.getDisplayName(), existingTerms.size());
                     }
-                    deleteTermCategorizationRelationships(existing, existingTerms.values());
+                    deleteTermCategorizationRelationships(storeObject, existingTerms.values());
                     break;
                 }
 
@@ -194,24 +260,24 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                                                                .stream()
                                                                .filter(t -> !existingTerms.containsKey(t.getTermGuid()))
                                                                .collect(Collectors.toSet());
-                createTermCategorizationRelationships(existing, toCreate);
+                createTermCategorizationRelationships(storeObject, toCreate);
 
                 Set<AtlasRelatedTermHeader> toUpdate = newTerms
                                                                .values()
                                                                .stream()
                                                                .filter(t -> updatedExistingTermRelation(existingTerms, t))
                                                                .collect(Collectors.toSet());
-                updateTermCategorizationRelationships(existing, toUpdate);
+                updateTermCategorizationRelationships(storeObject, toUpdate);
 
                 Set<AtlasRelatedTermHeader> toDelete = existingTerms
                                                                .values()
                                                                .stream()
                                                                .filter(t -> !newTerms.containsKey(t.getTermGuid()))
                                                                .collect(Collectors.toSet());
-                deleteTermCategorizationRelationships(existing, toDelete);
+                deleteTermCategorizationRelationships(storeObject, toDelete);
                 break;
             case DELETE:
-                deleteTermCategorizationRelationships(existing, existingTerms.values());
+                deleteTermCategorizationRelationships(storeObject, existingTerms.values());
                 break;
         }
     }
@@ -220,7 +286,7 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         return Objects.nonNull(term.getRelationGuid()) && !existingTerms.get(term.getTermGuid()).equals(term);
     }
 
-    private Map<String, AtlasRelatedTermHeader> getTerms(final AtlasGlossaryCategory category) {
+    private Map<String, AtlasRelatedTermHeader> getTerms(AtlasGlossaryCategory category) {
         if (Objects.nonNull(category.getTerms())) {
             Map<String, AtlasRelatedTermHeader> map = new HashMap<>();
             for (AtlasRelatedTermHeader t : category.getTerms()) {
@@ -236,9 +302,9 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         else return Collections.emptyMap();
     }
 
-    private void createTermCategorizationRelationships(AtlasGlossaryCategory existing, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
+    private void createTermCategorizationRelationships(AtlasGlossaryCategory storeObject, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
-            Set<AtlasRelatedTermHeader> existingTerms = existing.getTerms();
+            Set<AtlasRelatedTermHeader> existingTerms = storeObject.getTerms();
             for (AtlasRelatedTermHeader term : terms) {
                 if (Objects.isNull(term.getTermGuid())) {
                     throw new AtlasBaseException(AtlasErrorCode.MISSING_TERM_ID_FOR_CATEGORIZATION);
@@ -250,19 +316,19 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                         continue;
                     }
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating relation between category = {} and term = {}", existing.getGuid(), term.getDisplayText());
+                        LOG.debug("Creating relation between category = {} and term = {}", storeObject.getGuid(), term.getDisplayText());
                     }
-                    createRelationship(defineCategorizedTerm(existing.getGuid(), term));
+                    createRelationship(defineCategorizedTerm(storeObject.getGuid(), term));
                 }
             }
         }
     }
 
-    private void updateTermCategorizationRelationships(AtlasGlossaryCategory existing, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
+    private void updateTermCategorizationRelationships(AtlasGlossaryCategory storeObject, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
             for (AtlasRelatedTermHeader term : terms) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Updating term relation with category = {}, term = {}", existing.getDisplayName(), term.getDisplayText());
+                    LOG.debug("Updating term relation with category = {}, term = {}", storeObject.getDisplayName(), term.getDisplayText());
                 }
                 AtlasRelationship relationship = relationshipStore.getById(term.getRelationGuid());
                 updateRelationshipAttributes(relationship, term);
@@ -271,44 +337,53 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         }
     }
 
-    private void deleteTermCategorizationRelationships(AtlasGlossaryCategory existing, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
+    private void deleteTermCategorizationRelationships(AtlasGlossaryCategory storeObject, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
             for (AtlasRelatedTermHeader term : terms) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Creating term relation with category = {}, terms = {}", existing.getDisplayName(), term.getDisplayText());
+                    LOG.debug("Creating term relation with category = {}, terms = {}", storeObject.getDisplayName(), term.getDisplayText());
                 }
                 relationshipStore.deleteById(term.getRelationGuid());
             }
         }
     }
 
-    private void processCategoryChildren(AtlasGlossaryCategory updatedCategory, AtlasGlossaryCategory existing, RelationshipOperation op) throws AtlasBaseException {
+    private void processCategoryChildren(AtlasGlossaryCategory storeObject, AtlasGlossaryCategory updatedCategory, RelationshipOperation op, Map<String, AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
         Map<String, AtlasRelatedCategoryHeader> newChildren      = getChildren(updatedCategory);
-        Map<String, AtlasRelatedCategoryHeader> existingChildren = getChildren(existing);
+        Map<String, AtlasRelatedCategoryHeader> existingChildren = getChildren(storeObject);
         switch (op) {
             case CREATE:
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Creating new children, category = {}, children = {}", existing.getDisplayName(),
+                    LOG.debug("Creating new children, category = {}, children = {}", storeObject.getDisplayName(),
                               Objects.nonNull(newChildren) ? newChildren.size() : "none");
                 }
-                createCategoryRelationships(existing, newChildren.values());
+                createCategoryRelationships(storeObject, newChildren.values());
+
+                // New children added, qualifiedName needs recomputation
+                updateChildCategories(storeObject, newChildren.values(), impactedCategories, false);
                 break;
             case UPDATE:
                 // Create new children
                 if (MapUtils.isEmpty(existingChildren)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new children, category = {}, children = {}", existing.getDisplayName(),
+                        LOG.debug("Creating new children, category = {}, children = {}", storeObject.getDisplayName(),
                                   Objects.nonNull(newChildren) ? newChildren.size() : "none");
                     }
-                    createCategoryRelationships(existing, newChildren.values());
+                    createCategoryRelationships(storeObject, newChildren.values());
+
+                    // New children added, qualifiedName needs recomputation
+                    updateChildCategories(storeObject, newChildren.values(), impactedCategories, false);
                     break;
                 }
                 // Delete current children
                 if (MapUtils.isEmpty(newChildren)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Deleting children, category = {}, children = {}", existing.getDisplayName(), existingChildren.size());
+                        LOG.debug("Deleting children, category = {}, children = {}", storeObject.getDisplayName(), existingChildren.size());
                     }
-                    deleteCategoryRelationships(existing, existingChildren.values());
+                    deleteCategoryRelationships(storeObject, existingChildren.values());
+
+                    // Re-compute the qualifiedName for all children
+                    updateChildCategories(storeObject, existingChildren.values(), impactedCategories, true);
                     break;
                 }
 
@@ -317,24 +392,26 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                                                                    .stream()
                                                                    .filter(c -> !existingChildren.containsKey(c.getCategoryGuid()))
                                                                    .collect(Collectors.toSet());
-                createCategoryRelationships(existing, toCreate);
+                createCategoryRelationships(storeObject, toCreate);
+                // New children added, qualifiedName needs recomputation
+                updateChildCategories(storeObject, toCreate, impactedCategories, false);
 
                 Set<AtlasRelatedCategoryHeader> toUpdate = newChildren
                                                                    .values()
                                                                    .stream()
                                                                    .filter(c -> updatedExistingCategoryRelation(existingChildren, c))
                                                                    .collect(Collectors.toSet());
-                updateCategoryRelationships(existing, toUpdate);
+                updateCategoryRelationships(storeObject, toUpdate);
 
                 Set<AtlasRelatedCategoryHeader> toDelete = existingChildren
                                                                    .values()
                                                                    .stream()
                                                                    .filter(c -> !newChildren.containsKey(c.getCategoryGuid()))
                                                                    .collect(Collectors.toSet());
-                deleteCategoryRelationships(existing, toDelete);
+                deleteCategoryRelationships(storeObject, toDelete);
                 break;
             case DELETE:
-                deleteCategoryRelationships(existing, existingChildren.values());
+                deleteCategoryRelationships(storeObject, existingChildren.values());
                 break;
         }
     }
@@ -343,7 +420,7 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         return Objects.nonNull(header.getRelationGuid()) && !header.equals(existingChildren.get(header.getCategoryGuid()));
     }
 
-    private Map<String, AtlasRelatedCategoryHeader> getChildren(final AtlasGlossaryCategory category) {
+    private Map<String, AtlasRelatedCategoryHeader> getChildren(AtlasGlossaryCategory category) {
         if (Objects.nonNull(category.getChildrenCategories())) {
             Map<String, AtlasRelatedCategoryHeader> map = new HashMap<>();
             for (AtlasRelatedCategoryHeader c : category.getChildrenCategories()) {
@@ -357,9 +434,9 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         else return Collections.emptyMap();
     }
 
-    private void createCategoryRelationships(AtlasGlossaryCategory existing, Collection<AtlasRelatedCategoryHeader> newChildren) throws AtlasBaseException {
+    private void createCategoryRelationships(AtlasGlossaryCategory storeObject, Collection<AtlasRelatedCategoryHeader> newChildren) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(newChildren)) {
-            Set<AtlasRelatedCategoryHeader> existingChildren = existing.getChildrenCategories();
+            Set<AtlasRelatedCategoryHeader> existingChildren = storeObject.getChildrenCategories();
             for (AtlasRelatedCategoryHeader child : newChildren) {
                 if (Objects.nonNull(existingChildren) && existingChildren.contains(child)) {
                     if (DEBUG_ENABLED) {
@@ -376,11 +453,11 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                 childCategory.setGuid(child.getCategoryGuid());
                 childCategory = dataAccess.load(childCategory);
 
-                if (StringUtils.equals(existing.getAnchor().getGlossaryGuid(), childCategory.getAnchor().getGlossaryGuid())) {
+                if (StringUtils.equals(storeObject.getAnchor().getGlossaryGuid(), childCategory.getAnchor().getGlossaryGuid())) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new child, category = {}, child = {}", existing.getDisplayName(), child.getDisplayText());
+                        LOG.debug("Creating new child, category = {}, child = {}", storeObject.getDisplayName(), child.getDisplayText());
                     }
-                    createRelationship(defineCategoryHierarchyLink(existing.getGuid(), child));
+                    createRelationship(defineCategoryHierarchyLink(storeObject.getGuid(), child));
                 } else {
                     throw new AtlasBaseException(AtlasErrorCode.INVALID_CHILD_CATEGORY_DIFFERENT_GLOSSARY, child.getCategoryGuid());
                 }
@@ -389,11 +466,11 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         }
     }
 
-    private void updateCategoryRelationships(AtlasGlossaryCategory existing, Collection<AtlasRelatedCategoryHeader> toUpdate) throws AtlasBaseException {
+    private void updateCategoryRelationships(AtlasGlossaryCategory storeObject, Collection<AtlasRelatedCategoryHeader> toUpdate) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(toUpdate)) {
             for (AtlasRelatedCategoryHeader categoryHeader : toUpdate) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Updating child, category = {}, child = {}", existing.getDisplayName(), categoryHeader.getDisplayText());
+                    LOG.debug("Updating child, category = {}, child = {}", storeObject.getDisplayName(), categoryHeader.getDisplayText());
                 }
                 AtlasRelationship childRelationship = relationshipStore.getById(categoryHeader.getRelationGuid());
                 updateRelationshipAttributes(childRelationship, categoryHeader);
@@ -402,11 +479,11 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         }
     }
 
-    private void deleteCategoryRelationships(AtlasGlossaryCategory existing, Collection<AtlasRelatedCategoryHeader> existingChildren) throws AtlasBaseException {
+    private void deleteCategoryRelationships(AtlasGlossaryCategory storeObject, Collection<AtlasRelatedCategoryHeader> existingChildren) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(existingChildren)) {
             for (AtlasRelatedCategoryHeader child : existingChildren) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Deleting child, category = {}, child = {}", existing.getDisplayName(), child.getDisplayText());
+                    LOG.debug("Deleting child, category = {}, child = {}", storeObject.getDisplayName(), child.getDisplayText());
                 }
                 relationshipStore.deleteById(child.getRelationGuid());
             }
@@ -453,4 +530,56 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         }
     }
 
+    private void updateChildCategories(AtlasGlossaryCategory parentCategory, Collection<AtlasRelatedCategoryHeader> childCategories, Map<String, AtlasGlossaryCategory> impactedCategories, boolean isParentRemoved) throws AtlasBaseException {
+        if (CollectionUtils.isEmpty(childCategories)) {
+            return;
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Recomputing qualifiedName for {} children of category(guid={}, qualifiedName={})", childCategories.size(), parentCategory.getGuid(), parentCategory.getQualifiedName());
+        }
+
+        String parentAnchorGuid = parentCategory.getAnchor().getGlossaryGuid();
+
+        for (AtlasRelatedCategoryHeader childCategoryHeader : childCategories) {
+            AtlasGlossaryCategory child           = dataAccess.load(getAtlasGlossaryCategorySkeleton(childCategoryHeader.getCategoryGuid()));
+            String                qualifiedName   = child.getDisplayName() + ".";
+            String                childAnchorGuid = child.getAnchor().getGlossaryGuid();
+            if (isParentRemoved) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Parent removed, deriving qualifiedName using Glossary");
+                }
+                AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(childAnchorGuid));
+                qualifiedName += glossary.getQualifiedName();
+                child.setParentCategory(null);
+            } else {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Using parent to derive qualifiedName");
+                }
+                qualifiedName += parentCategory.getQualifiedName();
+            }
+            child.setQualifiedName(qualifiedName);
+
+            if (!StringUtils.equals(childAnchorGuid, parentAnchorGuid)){
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Child anchor guid({}) doesn't match parent anchor guid({}). Updating child anchor", childAnchorGuid, parentAnchorGuid);
+                }
+                // Remove old glossary relation
+                relationshipStore.deleteById(child.getAnchor().getRelationGuid());
+                // Link to new glossary
+                createRelationship(defineCategoryAnchorRelation(parentAnchorGuid, child.getGuid()));
+                // Update the child's anchor GUID
+                child.getAnchor().setGlossaryGuid(parentAnchorGuid);
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Derived qualifiedName = {}", qualifiedName);
+            }
+
+            // Collect all affected/impacted categories in this accumulator. All impacted categories will be saved as a part of post processing
+            impactedCategories.put(child.getGuid(), child);
+            updateChildCategories(child, child.getChildrenCategories(), impactedCategories, false);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/atlas/blob/66f8ae16/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java b/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java
index e63c519..bc9fe2a 100644
--- a/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java
+++ b/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java
@@ -50,6 +50,10 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static org.apache.atlas.glossary.GlossaryUtils.getAtlasGlossaryCategorySkeleton;
+import static org.apache.atlas.glossary.GlossaryUtils.getAtlasGlossaryTermSkeleton;
+import static org.apache.atlas.glossary.GlossaryUtils.getGlossarySkeleton;
+
 @Service
 public class GlossaryService {
     private static final Logger  LOG           = LoggerFactory.getLogger(GlossaryService.class);
@@ -91,7 +95,7 @@ public class GlossaryService {
         List<AtlasGlossary> ret;
         List<String>        guidsToLoad = paginationHelper.getPaginatedList();
         if (CollectionUtils.isNotEmpty(guidsToLoad)) {
-            ret = guidsToLoad.stream().map(GlossaryService::getGlossarySkeleton).collect(Collectors.toList());
+            ret = guidsToLoad.stream().map(GlossaryUtils::getGlossarySkeleton).collect(Collectors.toList());
             Iterable<AtlasGlossary> glossaries = dataAccess.load(ret);
             ret.clear();
 
@@ -139,13 +143,13 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_ALREADY_EXISTS, atlasGlossary.getQualifiedName());
         }
 
-        AtlasGlossary saved = dataAccess.save(atlasGlossary);
+        AtlasGlossary storeObject = dataAccess.save(atlasGlossary);
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.createGlossary() : {}", saved);
+            LOG.debug("<== GlossaryService.createGlossary() : {}", storeObject);
         }
 
-        return saved;
+        return storeObject;
     }
 
     /**
@@ -238,20 +242,20 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "DisplayName can't be null/empty");
         }
 
-        AtlasGlossary ret = dataAccess.load(atlasGlossary);
+        AtlasGlossary storeObject = dataAccess.load(atlasGlossary);
 
-        if (!ret.equals(atlasGlossary)) {
-            atlasGlossary.setGuid(ret.getGuid());
-            atlasGlossary.setQualifiedName(ret.getQualifiedName());
+        if (!storeObject.equals(atlasGlossary)) {
+            atlasGlossary.setGuid(storeObject.getGuid());
+            atlasGlossary.setQualifiedName(storeObject.getQualifiedName());
 
-            ret = dataAccess.save(atlasGlossary);
-            setInfoForRelations(ret);
+            storeObject = dataAccess.save(atlasGlossary);
+            setInfoForRelations(storeObject);
         }
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.updateGlossary() : {}", ret);
+            LOG.debug("<== GlossaryService.updateGlossary() : {}", storeObject);
         }
-        return ret;
+        return storeObject;
     }
 
     @GraphTransaction
@@ -263,13 +267,13 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryGuid is null/empty");
         }
 
-        AtlasGlossary existing = dataAccess.load(getGlossarySkeleton(glossaryGuid));
+        AtlasGlossary storeObject = dataAccess.load(getGlossarySkeleton(glossaryGuid));
 
-        Set<AtlasRelatedTermHeader> terms = existing.getTerms();
-        deleteTerms(existing, terms);
+        Set<AtlasRelatedTermHeader> terms = storeObject.getTerms();
+        deleteTerms(storeObject, terms);
 
-        Set<AtlasRelatedCategoryHeader> categories = existing.getCategories();
-        deleteCategories(existing, categories);
+        Set<AtlasRelatedCategoryHeader> categories = storeObject.getCategories();
+        deleteCategories(storeObject, categories);
 
         // Once all relations are deleted, then delete the Glossary
         dataAccess.delete(glossaryGuid);
@@ -314,31 +318,26 @@ public class GlossaryService {
         if (Objects.isNull(glossaryTerm.getAnchor())) {
             throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR);
         }
-        if (StringUtils.isEmpty(glossaryTerm.getQualifiedName())) {
-            String displayName  = glossaryTerm.getDisplayName();
-            String glossaryName = glossaryTerm.getAnchor().getDisplayText();
-            if (StringUtils.isEmpty(displayName) || StringUtils.isEmpty(glossaryName)) {
-                throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_QUALIFIED_NAME_CANT_BE_DERIVED);
-            } else {
-                glossaryTerm.setQualifiedName(displayName + "@" + glossaryName);
-            }
+        if (StringUtils.isEmpty(glossaryTerm.getDisplayName())) {
+            throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_QUALIFIED_NAME_CANT_BE_DERIVED);
         }
 
+        // This might fail for the case when the term's qualifiedName has been updated and the duplicate request comes in with old name
         if (termExists(glossaryTerm)) {
             throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_ALREADY_EXISTS, glossaryTerm.getQualifiedName());
         }
 
-        AtlasGlossaryTerm existing = dataAccess.save(glossaryTerm);
-        glossaryTermUtils.processTermRelations(glossaryTerm, existing, GlossaryUtils.RelationshipOperation.CREATE);
+        AtlasGlossaryTerm storeObject = dataAccess.save(glossaryTerm);
+        glossaryTermUtils.processTermRelations(storeObject, glossaryTerm, GlossaryUtils.RelationshipOperation.CREATE);
 
         // Re-load term after handling relations
-        existing = dataAccess.load(glossaryTerm);
-        setInfoForRelations(existing);
+        storeObject = dataAccess.load(glossaryTerm);
+        setInfoForRelations(storeObject);
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.create() : {}", existing);
+            LOG.debug("<== GlossaryService.create() : {}", storeObject);
         }
-        return existing;
+        return storeObject;
     }
 
     @GraphTransaction
@@ -378,28 +377,29 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "DisplayName can't be null/empty");
         }
 
-        AtlasGlossaryTerm existing = dataAccess.load(atlasGlossaryTerm);
-        AtlasGlossaryTerm updated  = atlasGlossaryTerm;
-        if (!existing.equals(updated)) {
+        AtlasGlossaryTerm storeObject = dataAccess.load(atlasGlossaryTerm);
+        if (!storeObject.equals(atlasGlossaryTerm)) {
             try {
-                updated.setGuid(existing.getGuid());
-                updated.setQualifiedName(existing.getQualifiedName());
+                atlasGlossaryTerm.setGuid(storeObject.getGuid());
+                atlasGlossaryTerm.setQualifiedName(storeObject.getQualifiedName());
 
-                atlasGlossaryTerm = dataAccess.save(updated);
+                storeObject = dataAccess.save(atlasGlossaryTerm);
             } catch (AtlasBaseException e) {
                 LOG.debug("Glossary term had no immediate attr updates. Exception: {}", e.getMessage());
             } finally {
-                glossaryTermUtils.processTermRelations(atlasGlossaryTerm, existing, GlossaryUtils.RelationshipOperation.UPDATE);
+                glossaryTermUtils.processTermRelations(storeObject, atlasGlossaryTerm, GlossaryUtils.RelationshipOperation.UPDATE);
             }
 
         }
 
-        updated = dataAccess.load(atlasGlossaryTerm);
-        setInfoForRelations(updated);
+        storeObject = dataAccess.load(atlasGlossaryTerm);
+        setInfoForRelations(storeObject);
+
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.updateTerm() : {}", updated);
+            LOG.debug("<== GlossaryService.updateTerm() : {}", storeObject);
         }
-        return updated;
+
+        return storeObject;
     }
 
     @GraphTransaction
@@ -411,13 +411,13 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "termGuid is null/empty");
         }
 
-        AtlasGlossaryTerm existing = dataAccess.load(getAtlasGlossaryTermSkeleton(termGuid));
+        AtlasGlossaryTerm storeObject = dataAccess.load(getAtlasGlossaryTermSkeleton(termGuid));
 
         // Remove term from Glossary
-        glossaryTermUtils.processTermRelations(existing, existing, GlossaryUtils.RelationshipOperation.DELETE);
+        glossaryTermUtils.processTermRelations(storeObject, storeObject, GlossaryUtils.RelationshipOperation.DELETE);
 
         // Remove term associations with Entities
-        glossaryTermUtils.processTermDissociation(existing, existing.getAssignedEntities());
+        glossaryTermUtils.processTermDissociation(storeObject, storeObject.getAssignedEntities());
 
         // Now delete the term
         dataAccess.delete(termGuid);
@@ -489,33 +489,39 @@ public class GlossaryService {
         if (Objects.isNull(glossaryCategory.getAnchor())) {
             throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR);
         }
-        if (StringUtils.isEmpty(glossaryCategory.getQualifiedName())) {
-            String displayName  = glossaryCategory.getDisplayName();
-            String glossaryName = glossaryCategory.getAnchor().getDisplayText();
-            if (StringUtils.isEmpty(displayName) || StringUtils.isEmpty(glossaryName)) {
-                throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_CATEGORY_QUALIFIED_NAME_CANT_BE_DERIVED);
-            } else {
-                glossaryCategory.setQualifiedName(displayName + "@" + glossaryName);
-            }
+        if (Objects.isNull(glossaryCategory.getDisplayName())) {
+            throw new AtlasBaseException(AtlasErrorCode.MISSING_CATEGORY_DISPLAY_NAME);
         }
 
+        // This might fail for the case when the category's qualifiedName has been updated during a hierarchy change
+        // and the duplicate request comes in with old name
         if (categoryExists(glossaryCategory)) {
             throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_CATEGORY_ALREADY_EXISTS, glossaryCategory.getQualifiedName());
         }
 
-        AtlasGlossaryCategory saved = dataAccess.save(glossaryCategory);
+        AtlasGlossaryCategory storeObject = dataAccess.save(glossaryCategory);
+
+        // Attempt relation creation and gather all impacted categories
+        Map<String, AtlasGlossaryCategory> impactedCategories = glossaryCategoryUtils.processCategoryRelations(storeObject, glossaryCategory, GlossaryUtils.RelationshipOperation.CREATE);
 
-        // Attempt relation creation
-        glossaryCategoryUtils.processCategoryRelations(glossaryCategory, saved, GlossaryUtils.RelationshipOperation.CREATE);
-        saved = dataAccess.load(glossaryCategory);
+        // Re save the categories in case any qualifiedName change has occurred
+        dataAccess.save(impactedCategories.values());
+
+        // Since the current category is also affected, we need to update qualifiedName and save again
+        if (!StringUtils.equals(glossaryCategory.getQualifiedName(), storeObject.getQualifiedName())) {
+            glossaryCategory.setQualifiedName(storeObject.getQualifiedName());
+            storeObject = dataAccess.save(glossaryCategory);
+        } else {
+            storeObject = dataAccess.load(glossaryCategory);
+        }
 
-        setInfoForRelations(saved);
+        setInfoForRelations(storeObject);
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.createCategory() : {}", saved);
+            LOG.debug("<== GlossaryService.createCategory() : {}", storeObject);
         }
 
-        return saved;
+        return storeObject;
     }
 
     @GraphTransaction
@@ -552,30 +558,36 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "DisplayName can't be null/empty");
         }
 
-        AtlasGlossaryCategory existing = dataAccess.load(glossaryCategory);
-        AtlasGlossaryCategory ret      = glossaryCategory;
+        AtlasGlossaryCategory storeObject = dataAccess.load(glossaryCategory);
 
-        if (!existing.equals(glossaryCategory)) {
+        if (!storeObject.equals(glossaryCategory)) {
             try {
-                glossaryCategory.setGuid(existing.getGuid());
-                glossaryCategory.setQualifiedName(existing.getQualifiedName());
+                glossaryCategory.setGuid(storeObject.getGuid());
+                glossaryCategory.setQualifiedName(storeObject.getQualifiedName());
 
-                ret = dataAccess.save(glossaryCategory);
+                storeObject = dataAccess.save(glossaryCategory);
             } catch (AtlasBaseException e) {
                 LOG.debug("No immediate attribute update. Exception: {}", e.getMessage());
             } finally {
-                glossaryCategoryUtils.processCategoryRelations(glossaryCategory, existing, GlossaryUtils.RelationshipOperation.UPDATE);
+                Map<String, AtlasGlossaryCategory> impactedCategories = glossaryCategoryUtils.processCategoryRelations(storeObject, glossaryCategory, GlossaryUtils.RelationshipOperation.UPDATE);
+                dataAccess.save(impactedCategories.values());
+                // Since the current category is also affected, we need to update qualifiedName and save again
+                if (!StringUtils.equals(glossaryCategory.getQualifiedName(), storeObject.getQualifiedName())){
+                    glossaryCategory.setQualifiedName(storeObject.getQualifiedName());
+                    storeObject = dataAccess.save(glossaryCategory);
+                } else {
+                    storeObject = dataAccess.load(glossaryCategory);
+                }
             }
         }
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.updateCategory() : {}", ret);
+            LOG.debug("<== GlossaryService.updateCategory() : {}", storeObject);
         }
-        ret = dataAccess.load(glossaryCategory);
 
-        setInfoForRelations(ret);
+        setInfoForRelations(storeObject);
 
-        return ret;
+        return storeObject;
     }
 
     @GraphTransaction
@@ -587,10 +599,10 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Category guid is null/empty");
         }
 
-        AtlasGlossaryCategory existing = dataAccess.load(getAtlasGlossaryCategorySkeleton(categoryGuid));
+        AtlasGlossaryCategory storeObject = dataAccess.load(getAtlasGlossaryCategorySkeleton(categoryGuid));
 
         // Delete all relations
-        glossaryCategoryUtils.processCategoryRelations(existing, existing, GlossaryUtils.RelationshipOperation.DELETE);
+        glossaryCategoryUtils.processCategoryRelations(storeObject, storeObject, GlossaryUtils.RelationshipOperation.DELETE);
 
         // Now delete the category
         dataAccess.delete(categoryGuid);
@@ -825,12 +837,6 @@ public class GlossaryService {
         return ret;
     }
 
-    private static AtlasGlossary getGlossarySkeleton(String glossaryGuid) {
-        AtlasGlossary glossary = new AtlasGlossary();
-        glossary.setGuid(glossaryGuid);
-        return glossary;
-    }
-
     private boolean glossaryExists(AtlasGlossary atlasGlossary) {
         AtlasVertex vertex = AtlasGraphUtilsV1.findByUniqueAttributes(atlasTypeRegistry.getEntityTypeByName(GlossaryUtils.ATLAS_GLOSSARY_TYPENAME), new HashMap<String, Object>() {{
             put(QUALIFIED_NAME_ATTR, atlasGlossary.getQualifiedName());
@@ -852,10 +858,10 @@ public class GlossaryService {
         return Objects.nonNull(vertex);
     }
 
-    private void deleteCategories(final AtlasGlossary existing, final Collection<AtlasRelatedCategoryHeader> categories) throws AtlasBaseException {
+    private void deleteCategories(final AtlasGlossary storeObject, final Collection<AtlasRelatedCategoryHeader> categories) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(categories)) {
             if (DEBUG_ENABLED) {
-                LOG.debug("Deleting categories within glossary guid = {}", existing.getGuid());
+                LOG.debug("Deleting categories within glossary guid = {}", storeObject.getGuid());
             }
             for (AtlasRelatedCategoryHeader category : categories) {
                 // Delete category
@@ -864,10 +870,10 @@ public class GlossaryService {
         }
     }
 
-    private void deleteTerms(final AtlasGlossary existing, final Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
+    private void deleteTerms(final AtlasGlossary storeObject, final Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
             if (DEBUG_ENABLED) {
-                LOG.debug("Deleting terms within glossary guid = {}", existing.getGuid());
+                LOG.debug("Deleting terms within glossary guid = {}", storeObject.getGuid());
             }
             for (AtlasRelatedTermHeader term : terms) {
                 // Delete the term
@@ -876,18 +882,6 @@ public class GlossaryService {
         }
     }
 
-    private AtlasGlossaryTerm getAtlasGlossaryTermSkeleton(final String termGuid) {
-        AtlasGlossaryTerm glossaryTerm = new AtlasGlossaryTerm();
-        glossaryTerm.setGuid(termGuid);
-        return glossaryTerm;
-    }
-
-    private AtlasGlossaryCategory getAtlasGlossaryCategorySkeleton(final String categoryGuid) {
-        AtlasGlossaryCategory glossaryCategory = new AtlasGlossaryCategory();
-        glossaryCategory.setGuid(categoryGuid);
-        return glossaryCategory;
-    }
-
     private void setInfoForRelations(final AtlasGlossary ret) throws AtlasBaseException {
         if (Objects.nonNull(ret.getTerms())) {
             setInfoForTerms(ret.getTerms());

http://git-wip-us.apache.org/repos/asf/atlas/blob/66f8ae16/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java b/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java
index 6977369..2c38d31 100644
--- a/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java
+++ b/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java
@@ -19,6 +19,7 @@ package org.apache.atlas.glossary;
 
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.glossary.AtlasGlossary;
 import org.apache.atlas.model.glossary.AtlasGlossaryTerm;
 import org.apache.atlas.model.glossary.relations.AtlasGlossaryHeader;
 import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader;
@@ -53,14 +54,14 @@ public class GlossaryTermUtils extends GlossaryUtils {
         super(relationshipStore, typeRegistry, dataAccess);
     }
 
-    public void processTermRelations(AtlasGlossaryTerm updatedTerm, AtlasGlossaryTerm existing, RelationshipOperation op) throws AtlasBaseException {
+    public void processTermRelations(AtlasGlossaryTerm storeObject, AtlasGlossaryTerm updatedTerm, RelationshipOperation op) throws AtlasBaseException {
         if (DEBUG_ENABLED) {
-            LOG.debug("==> GlossaryTermUtils.processTermRelations({}, {}, {})", updatedTerm, existing, op);
+            LOG.debug("==> GlossaryTermUtils.processTermRelations({}, {}, {})", storeObject, updatedTerm, op);
         }
 
-        processTermAnchor(updatedTerm, existing, op);
-        processRelatedTerms(updatedTerm, existing, op);
-        processAssociatedCategories(updatedTerm, existing, op);
+        processTermAnchor(storeObject, updatedTerm, op);
+        processRelatedTerms(storeObject, updatedTerm, op);
+        processAssociatedCategories(storeObject, updatedTerm, op);
 
         if (DEBUG_ENABLED) {
             LOG.debug("<== GlossaryTermUtils.processTermRelations()");
@@ -130,12 +131,16 @@ public class GlossaryTermUtils extends GlossaryUtils {
         }
     }
 
-    private boolean isRelationshipGuidSame(final AtlasRelatedObjectId existing, final AtlasRelatedObjectId relatedObjectId) {
-        return StringUtils.equals(relatedObjectId.getRelationshipGuid(), existing.getRelationshipGuid());
+    private boolean isRelationshipGuidSame(AtlasRelatedObjectId storeObject, AtlasRelatedObjectId relatedObjectId) {
+        return StringUtils.equals(relatedObjectId.getRelationshipGuid(), storeObject.getRelationshipGuid());
     }
 
-    private void processTermAnchor(AtlasGlossaryTerm updatedTerm, AtlasGlossaryTerm existing, RelationshipOperation op) throws AtlasBaseException {
-        AtlasGlossaryHeader existingAnchor    = existing.getAnchor();
+    private void processTermAnchor(AtlasGlossaryTerm storeObject, AtlasGlossaryTerm updatedTerm, RelationshipOperation op) throws AtlasBaseException {
+        if (Objects.isNull(updatedTerm.getAnchor()) && op != RelationshipOperation.DELETE) {
+            throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR);
+        }
+
+        AtlasGlossaryHeader existingAnchor    = storeObject.getAnchor();
         AtlasGlossaryHeader updatedTermAnchor = updatedTerm.getAnchor();
 
         switch (op) {
@@ -144,9 +149,19 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     throw new AtlasBaseException(AtlasErrorCode.INVALID_NEW_ANCHOR_GUID);
                 } else {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating relation between glossary = {} and term = {}", updatedTermAnchor.getGlossaryGuid(), existing.getDisplayName());
+                        LOG.debug("Creating new term anchor, category = {}, glossary = {}", storeObject.getGuid(), updatedTerm.getAnchor().getGlossaryGuid());
+                    }
+
+                    // Derive the qualifiedName
+                    String        anchorGlossaryGuid = updatedTermAnchor.getGlossaryGuid();
+                    AtlasGlossary glossary           = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+                    storeObject.setQualifiedName(storeObject.getDisplayName() + "@" + glossary.getQualifiedName());
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Derived qualifiedName = {}", storeObject.getQualifiedName());
                     }
-                    createRelationship(defineTermAnchorRelation(updatedTermAnchor.getGlossaryGuid(), existing.getGuid()));
+
+                    createRelationship(defineTermAnchorRelation(updatedTermAnchor.getGlossaryGuid(), storeObject.getGuid()));
                 }
                 break;
             case UPDATE:
@@ -156,10 +171,23 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     }
 
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Updating relation between glossary = {} and term = {}", updatedTermAnchor.getGlossaryGuid(), existing.getDisplayName());
+                        LOG.debug("Updating term anchor, currAnchor = {}, newAnchor = {} and term = {}",
+                                  existingAnchor.getGlossaryGuid(),
+                                  updatedTermAnchor.getGlossaryGuid(),
+                                  storeObject.getDisplayName());
                     }
                     relationshipStore.deleteById(existingAnchor.getRelationGuid());
-                    createRelationship(defineTermAnchorRelation(updatedTermAnchor.getGlossaryGuid(), existing.getGuid()));
+
+                    // Derive the qualifiedName when anchor changes
+                    String        anchorGlossaryGuid = updatedTermAnchor.getGlossaryGuid();
+                    AtlasGlossary glossary           = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+                    storeObject.setQualifiedName(storeObject.getDisplayName() + "@" + glossary.getQualifiedName());
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Derived qualifiedName = {}", storeObject.getQualifiedName());
+                    }
+
+                    createRelationship(defineTermAnchorRelation(updatedTermAnchor.getGlossaryGuid(), storeObject.getGuid()));
                 }
                 break;
             case DELETE:
@@ -173,9 +201,9 @@ public class GlossaryTermUtils extends GlossaryUtils {
         }
     }
 
-    private void processRelatedTerms(AtlasGlossaryTerm updatedTerm, AtlasGlossaryTerm existing, RelationshipOperation op) throws AtlasBaseException {
+    private void processRelatedTerms(AtlasGlossaryTerm storeObject, AtlasGlossaryTerm updatedTerm, RelationshipOperation op) throws AtlasBaseException {
         Map<AtlasGlossaryTerm.Relation, Set<AtlasRelatedTermHeader>> newRelatedTerms      = updatedTerm.getRelatedTerms();
-        Map<AtlasGlossaryTerm.Relation, Set<AtlasRelatedTermHeader>> existingRelatedTerms = existing.getRelatedTerms();
+        Map<AtlasGlossaryTerm.Relation, Set<AtlasRelatedTermHeader>> existingRelatedTerms = storeObject.getRelatedTerms();
         switch (op) {
             case CREATE:
                 for (Map.Entry<AtlasGlossaryTerm.Relation, Set<AtlasRelatedTermHeader>> entry : newRelatedTerms.entrySet()) {
@@ -183,10 +211,10 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     Set<AtlasRelatedTermHeader> terms    = entry.getValue();
                     if (Objects.nonNull(terms)) {
                         if (DEBUG_ENABLED) {
-                            LOG.debug("{} relation {} for term = {}", op, relation, existing.getGuid());
+                            LOG.debug("{} relation {} for term = {}", op, relation, storeObject.getGuid());
                             LOG.debug("Related Term count = {}", terms.size());
                         }
-                        createTermRelationships(existing, relation, terms);
+                        createTermRelationships(storeObject, relation, terms);
                     }
                 }
                 break;
@@ -201,7 +229,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
                             LOG.debug("Creating new term relations, relation = {}, terms = {}", relation,
                                       Objects.nonNull(newTermHeaders) ? newTermHeaders.size() : "none");
                         }
-                        createTermRelationships(existing, relation, newTermHeaders.values());
+                        createTermRelationships(storeObject, relation, newTermHeaders.values());
                         continue;
                     }
 
@@ -230,7 +258,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
                                                                    .filter(t -> !newTermHeaders.containsKey(t.getTermGuid()))
                                                                    .collect(Collectors.toSet());
 
-                    createTermRelationships(existing, relation, toCreate);
+                    createTermRelationships(storeObject, relation, toCreate);
                     updateTermRelationships(relation, toUpdate);
                     deleteTermRelationships(relation, toDelete);
 
@@ -265,33 +293,33 @@ public class GlossaryTermUtils extends GlossaryUtils {
         return Objects.nonNull(header.getRelationGuid()) && !header.equals(existingTermHeaders.get(header.getTermGuid()));
     }
 
-    private void processAssociatedCategories(AtlasGlossaryTerm updatedTerm, AtlasGlossaryTerm existing, RelationshipOperation op) throws AtlasBaseException {
+    private void processAssociatedCategories(AtlasGlossaryTerm storeObject, AtlasGlossaryTerm updatedTerm, RelationshipOperation op) throws AtlasBaseException {
         Map<String, AtlasTermCategorizationHeader> newCategories      = getAssociatedCategories(updatedTerm);
-        Map<String, AtlasTermCategorizationHeader> existingCategories = getAssociatedCategories(existing);
+        Map<String, AtlasTermCategorizationHeader> existingCategories = getAssociatedCategories(storeObject);
         switch (op) {
             case CREATE:
                 if (Objects.nonNull(newCategories)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new term categorization, term = {}, categories = {}", existing.getGuid(), newCategories.size());
+                        LOG.debug("Creating new term categorization, term = {}, categories = {}", storeObject.getGuid(), newCategories.size());
                     }
-                    createTermCategorizationRelationships(existing, newCategories.values());
+                    createTermCategorizationRelationships(storeObject, newCategories.values());
                 }
                 break;
             case UPDATE:
                 // If no existing categories are present then create all existing ones
                 if (MapUtils.isEmpty(existingCategories)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new term categorization, term = {}, categories = {}", existing.getGuid(),
+                        LOG.debug("Creating new term categorization, term = {}, categories = {}", storeObject.getGuid(),
                                   Objects.nonNull(newCategories) ? newCategories.size() : "none");
                     }
-                    createTermCategorizationRelationships(existing, newCategories.values());
+                    createTermCategorizationRelationships(storeObject, newCategories.values());
                     break;
                 }
 
                 // If no new categories are present then delete all existing ones
                 if (MapUtils.isEmpty(newCategories)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Deleting term categorization, term = {}, categories = {}", existing.getGuid(), existingCategories.size());
+                        LOG.debug("Deleting term categorization, term = {}, categories = {}", storeObject.getGuid(), existingCategories.size());
                     }
                     deleteCategorizationRelationship(existingCategories.values());
                     break;
@@ -302,13 +330,13 @@ public class GlossaryTermUtils extends GlossaryUtils {
                                                                       .stream()
                                                                       .filter(c -> !existingCategories.containsKey(c.getCategoryGuid()))
                                                                       .collect(Collectors.toSet());
-                createTermCategorizationRelationships(existing, toCreate);
+                createTermCategorizationRelationships(storeObject, toCreate);
                 Set<AtlasTermCategorizationHeader> toUpdate = newCategories
                                                                       .values()
                                                                       .stream()
                                                                       .filter(c -> updatedExistingCategorizationRelation(existingCategories, c))
                                                                       .collect(Collectors.toSet());
-                updateTermCategorizationRelationships(existing, toUpdate);
+                updateTermCategorizationRelationships(storeObject, toUpdate);
                 Set<AtlasTermCategorizationHeader> toDelete = existingCategories
                                                                       .values()
                                                                       .stream()
@@ -326,7 +354,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
         return Objects.nonNull(header.getRelationGuid()) && !header.equals(existingCategories.get(header.getCategoryGuid()));
     }
 
-    private Map<String, AtlasTermCategorizationHeader> getAssociatedCategories(final AtlasGlossaryTerm term) {
+    private Map<String, AtlasTermCategorizationHeader> getAssociatedCategories(AtlasGlossaryTerm term) {
         if (Objects.nonNull(term.getCategories())) {
             Map<String, AtlasTermCategorizationHeader> map = new HashMap<>();
             for (AtlasTermCategorizationHeader c : term.getCategories()) {
@@ -341,9 +369,9 @@ public class GlossaryTermUtils extends GlossaryUtils {
         }
     }
 
-    private void createTermCategorizationRelationships(AtlasGlossaryTerm existing, Collection<AtlasTermCategorizationHeader> categories) throws AtlasBaseException {
+    private void createTermCategorizationRelationships(AtlasGlossaryTerm storeObject, Collection<AtlasTermCategorizationHeader> categories) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(categories)) {
-            Set<AtlasTermCategorizationHeader> existingCategories = existing.getCategories();
+            Set<AtlasTermCategorizationHeader> existingCategories = storeObject.getCategories();
             for (AtlasTermCategorizationHeader categorizationHeader : categories) {
                 if (Objects.nonNull(existingCategories) && existingCategories.contains(categorizationHeader)) {
                     if (DEBUG_ENABLED) {
@@ -352,18 +380,18 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     continue;
                 }
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Creating relation between term = {} and category = {}", existing.getGuid(), categorizationHeader.getDisplayText());
+                    LOG.debug("Creating relation between term = {} and category = {}", storeObject.getGuid(), categorizationHeader.getDisplayText());
                 }
-                createRelationship(defineCategorizedTerm(categorizationHeader, existing.getGuid()));
+                createRelationship(defineCategorizedTerm(categorizationHeader, storeObject.getGuid()));
             }
         }
     }
 
-    private void updateTermCategorizationRelationships(AtlasGlossaryTerm existing, Collection<AtlasTermCategorizationHeader> toUpdate) throws AtlasBaseException {
+    private void updateTermCategorizationRelationships(AtlasGlossaryTerm storeObject, Collection<AtlasTermCategorizationHeader> toUpdate) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(toUpdate)) {
             for (AtlasTermCategorizationHeader categorizationHeader : toUpdate) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Updating relation between term = {} and category = {}", existing.getGuid(), categorizationHeader.getDisplayText());
+                    LOG.debug("Updating relation between term = {} and category = {}", storeObject.getGuid(), categorizationHeader.getDisplayText());
                 }
                 AtlasRelationship relationship = relationshipStore.getById(categorizationHeader.getRelationGuid());
                 updateRelationshipAttributes(relationship, categorizationHeader);
@@ -383,12 +411,12 @@ public class GlossaryTermUtils extends GlossaryUtils {
         }
     }
 
-    private void createTermRelationships(AtlasGlossaryTerm existing, AtlasGlossaryTerm.Relation relation, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
+    private void createTermRelationships(AtlasGlossaryTerm storeObject, AtlasGlossaryTerm.Relation relation, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
             Map<String, AtlasRelatedTermHeader> existingRelations;
-            if (Objects.nonNull(existing.getRelatedTerms()) && Objects.nonNull(existing.getRelatedTerms().get(relation))) {
+            if (Objects.nonNull(storeObject.getRelatedTerms()) && Objects.nonNull(storeObject.getRelatedTerms().get(relation))) {
                 Map<String, AtlasRelatedTermHeader> map = new HashMap<>();
-                for (AtlasRelatedTermHeader t : existing.getRelatedTerms().get(relation)) {
+                for (AtlasRelatedTermHeader t : storeObject.getRelatedTerms().get(relation)) {
                     AtlasRelatedTermHeader header = map.get(t.getTermGuid());
                     if (header == null || (StringUtils.isEmpty(header.getRelationGuid()) && StringUtils.isNotEmpty(t.getRelationGuid()))) {
                         map.put(t.getTermGuid(), t);
@@ -406,7 +434,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     continue;
                 }
 
-                if (existing.getGuid().equals(term.getTermGuid())) {
+                if (storeObject.getGuid().equals(term.getTermGuid())) {
                     throw new AtlasBaseException(AtlasErrorCode.INVALID_TERM_RELATION_TO_SELF);
                 }
 
@@ -414,7 +442,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     LOG.debug("Creating new term relation = {}, terms = {}", relation, term.getDisplayText());
                 }
 
-                createRelationship(defineTermRelation(relation, existing.getGuid(), term));
+                createRelationship(defineTermRelation(relation, storeObject.getGuid(), term));
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/66f8ae16/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java b/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java
index e320144..cec4c23 100644
--- a/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java
+++ b/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java
@@ -19,6 +19,9 @@ package org.apache.atlas.glossary;
 
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.glossary.AtlasGlossary;
+import org.apache.atlas.model.glossary.AtlasGlossaryCategory;
+import org.apache.atlas.model.glossary.AtlasGlossaryTerm;
 import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader;
 import org.apache.atlas.model.instance.AtlasRelationship;
 import org.apache.atlas.repository.ogm.DataAccess;
@@ -64,6 +67,26 @@ public abstract class GlossaryUtils {
         this.dataAccess = dataAccess;
     }
 
+    public static AtlasGlossary getGlossarySkeleton(String glossaryGuid) {
+        AtlasGlossary glossary = new AtlasGlossary();
+        glossary.setGuid(glossaryGuid);
+        return glossary;
+    }
+
+    public static AtlasGlossaryTerm getAtlasGlossaryTermSkeleton(final String termGuid) {
+        AtlasGlossaryTerm glossaryTerm = new AtlasGlossaryTerm();
+        glossaryTerm.setGuid(termGuid);
+        return glossaryTerm;
+    }
+
+    public static AtlasGlossaryCategory getAtlasGlossaryCategorySkeleton(final String categoryGuid) {
+        AtlasGlossaryCategory glossaryCategory = new AtlasGlossaryCategory();
+        glossaryCategory.setGuid(categoryGuid);
+        return glossaryCategory;
+    }
+
+
+
     protected void createRelationship(AtlasRelationship relationship) throws AtlasBaseException {
         try {
             relationshipStore.create(relationship);