You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2019/03/06 15:50:39 UTC

[atlas] branch master updated: ATLAS-3063: updated entity create/update to enable relationship-type to be specified for relationship attributes

This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/master by this push:
     new 5651f93  ATLAS-3063: updated entity create/update to enable relationship-type to be specified for relationship attributes
5651f93 is described below

commit 5651f934f42c40933d668b2d6f00fb9f8d9d1d89
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Mon Mar 4 23:13:12 2019 -0800

    ATLAS-3063: updated entity create/update to enable relationship-type to be specified for relationship attributes
---
 .../atlas/model/instance/AtlasRelatedObjectId.java |  94 ++++++++---
 .../org/apache/atlas/type/AtlasEntityType.java     | 177 ++++++++++++---------
 .../apache/atlas/type/AtlasRelationshipType.java   |  18 +--
 .../org/apache/atlas/type/AtlasStructType.java     |   2 +-
 .../org/apache/atlas/utils/AtlasEntityUtil.java    |  22 ++-
 .../atlas/type/TestAtlasRelationshipType.java      |  20 +--
 .../atlas/discovery/EntityDiscoveryService.java    |   3 +-
 .../org/apache/atlas/discovery/SearchContext.java  |   3 +-
 .../apache/atlas/repository/graph/GraphHelper.java |  35 ++--
 .../atlas/repository/impexp/ExportService.java     |  22 +--
 .../repository/impexp/ExportTypeProcessor.java     |  24 +--
 .../graph/v2/AtlasEntityGraphDiscoveryV2.java      |  16 +-
 .../store/graph/v2/AtlasEntityStoreV2.java         |  11 +-
 .../store/graph/v2/AtlasGraphUtilsV2.java          |   4 -
 .../graph/v2/AtlasRelationshipDefStoreV2.java      |   1 +
 .../store/graph/v2/AtlasRelationshipStoreV2.java   |   5 +-
 .../store/graph/v2/EntityGraphMapper.java          |  21 +--
 .../store/graph/v2/EntityGraphRetriever.java       |  28 ++--
 18 files changed, 300 insertions(+), 206 deletions(-)

diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelatedObjectId.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelatedObjectId.java
index fde2629..7c57ccf 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelatedObjectId.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelatedObjectId.java
@@ -43,14 +43,17 @@ import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_
 public class AtlasRelatedObjectId extends AtlasObjectId implements Serializable {
     private static final long serialVersionUID = 1L;
 
+    public static final String KEY_RELATIONSHIP_TYPE       = "relationshipType";
     public static final String KEY_RELATIONSHIP_GUID       = "relationshipGuid";
+    public static final String KEY_RELATIONSHIP_STATUS     = "relationshipStatus";
     public static final String KEY_RELATIONSHIP_ATTRIBUTES = "relationshipAttributes";
 
-    private AtlasEntity.Status       entityStatus       = null;
-    private String                   displayText        = null;
-    private String                   relationshipGuid   = null;
-    private AtlasRelationship.Status relationshipStatus = null;
-    private AtlasStruct              relationshipAttributes;
+    private AtlasEntity.Status       entityStatus           = null;
+    private String                   displayText            = null;
+    private String                   relationshipType       = null;
+    private String                   relationshipGuid       = null;
+    private AtlasRelationship.Status relationshipStatus     = null;
+    private AtlasStruct              relationshipAttributes = null;
 
     public AtlasRelatedObjectId() { }
 
@@ -76,17 +79,76 @@ public class AtlasRelatedObjectId extends AtlasObjectId implements Serializable
         setRelationshipAttributes(relationshipAttributes);
     }
 
+    public AtlasRelatedObjectId(AtlasObjectId other) {
+        super(other);
+    }
+
+    public AtlasRelatedObjectId(Map objIdMap) {
+        super(objIdMap);
+
+        if (objIdMap != null) {
+            Object g = objIdMap.get(KEY_RELATIONSHIP_GUID);
+            Object t = objIdMap.get(KEY_RELATIONSHIP_TYPE);
+            Object a = objIdMap.get(KEY_RELATIONSHIP_ATTRIBUTES);
+            Object s = objIdMap.get(KEY_RELATIONSHIP_STATUS);
+
+            if (g != null) {
+                setRelationshipGuid(g.toString());
+            }
+
+            if (a instanceof Map) {
+                setRelationshipAttributes(new AtlasStruct((Map) a));
+            } else if (a instanceof AtlasStruct) {
+                setRelationshipAttributes(new AtlasStruct((AtlasStruct) a));
+            }
+
+            if (t != null) {
+                setRelationshipType(t.toString());
+            }
+
+            if (s != null) {
+                setRelationshipStatus(AtlasRelationship.Status.valueOf(s.toString()));
+            }
+        }
+    }
+
+    public AtlasEntity.Status getEntityStatus() {
+        return entityStatus;
+    }
+
+    public void setEntityStatus(AtlasEntity.Status entityStatus) {
+        this.entityStatus = entityStatus;
+    }
+
     public String getDisplayText() { return displayText; }
 
     public void setDisplayText(String displayText) { this.displayText = displayText; }
 
+    public String getRelationshipType() { return relationshipType; }
+
+    public void setRelationshipType(String relationshipType) { this.relationshipType = relationshipType; }
+
     public String getRelationshipGuid() { return relationshipGuid; }
 
     public void setRelationshipGuid(String relationshipGuid) { this.relationshipGuid = relationshipGuid; }
 
+    public AtlasRelationship.Status getRelationshipStatus() {
+        return relationshipStatus;
+    }
+
+    public void setRelationshipStatus(final AtlasRelationship.Status relationshipStatus) {
+        this.relationshipStatus = relationshipStatus;
+    }
+
     public AtlasStruct getRelationshipAttributes() { return relationshipAttributes; }
 
-    public void setRelationshipAttributes(AtlasStruct relationshipAttributes) { this.relationshipAttributes = relationshipAttributes; }
+    public void setRelationshipAttributes(AtlasStruct relationshipAttributes) {
+        this.relationshipAttributes = relationshipAttributes;
+
+        if (relationshipAttributes != null && relationshipAttributes.getTypeName() != null) {
+            setRelationshipType(relationshipAttributes.getTypeName());
+        }
+    }
 
     @Override
     public boolean equals(Object o) {
@@ -96,6 +158,7 @@ public class AtlasRelatedObjectId extends AtlasObjectId implements Serializable
         AtlasRelatedObjectId that = (AtlasRelatedObjectId) o;
         return Objects.equals(entityStatus, that.entityStatus) &&
                Objects.equals(displayText, that.displayText) &&
+               Objects.equals(relationshipType, that.relationshipType) &&
                Objects.equals(relationshipGuid, that.relationshipGuid) &&
                Objects.equals(relationshipStatus, that.relationshipStatus) &&
                Objects.equals(relationshipAttributes, that.relationshipAttributes);
@@ -103,7 +166,7 @@ public class AtlasRelatedObjectId extends AtlasObjectId implements Serializable
 
     @Override
     public int hashCode() {
-        return Objects.hash(super.hashCode(), displayText, relationshipGuid, relationshipStatus, relationshipAttributes);
+        return Objects.hash(super.hashCode(), displayText, relationshipType, relationshipGuid, relationshipStatus, relationshipAttributes);
     }
 
     @Override
@@ -121,6 +184,7 @@ public class AtlasRelatedObjectId extends AtlasObjectId implements Serializable
         super.toString(sb);
         sb.append("entityStatus='").append(entityStatus).append('\'');
         sb.append(", displayText='").append(displayText).append('\'');
+        sb.append(", relationshipType='").append(relationshipType).append('\'');
         sb.append(", relationshipGuid='").append(relationshipGuid).append('\'');
         sb.append(", relationshipStatus='").append(relationshipStatus).append('\'');
         sb.append(", relationshipAttributes=").append(relationshipAttributes);
@@ -128,20 +192,4 @@ public class AtlasRelatedObjectId extends AtlasObjectId implements Serializable
 
         return sb;
     }
-
-    public AtlasRelationship.Status getRelationshipStatus() {
-        return relationshipStatus;
-    }
-
-    public void setRelationshipStatus(final AtlasRelationship.Status relationshipStatus) {
-        this.relationshipStatus = relationshipStatus;
-    }
-
-    public AtlasEntity.Status getEntityStatus() {
-        return entityStatus;
-    }
-
-    public void setEntityStatus(AtlasEntity.Status entityStatus) {
-        this.entityStatus = entityStatus;
-    }
 }
\ No newline at end of file
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
index 8960703..ce61548 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -26,6 +26,7 @@ import org.apache.atlas.model.instance.AtlasStruct;
 import org.apache.atlas.model.typedef.AtlasEntityDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.type.AtlasBuiltInTypes.AtlasObjectIdType;
+import org.apache.atlas.utils.AtlasEntityUtil;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
@@ -33,6 +34,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -66,8 +68,7 @@ public class AtlasEntityType extends AtlasStructType {
     private Set<String>                              allSubTypes                = Collections.emptySet();
     private Set<String>                              typeAndAllSubTypes         = Collections.emptySet();
     private Set<String>                              typeAndAllSuperTypes       = Collections.emptySet();
-    private Map<String, AtlasAttribute>              relationshipAttributes     = Collections.emptyMap();
-    private Map<String, List<AtlasRelationshipType>> relationshipAttributesType = Collections.emptyMap();
+    private Map<String, Map<String, AtlasAttribute>> relationshipAttributes     = Collections.emptyMap();
     private List<AtlasAttribute>                     ownedRefAttributes         = Collections.emptyList();
     private String                                   typeAndAllSubTypesQryStr   = "";
     private boolean                                  isInternalType             = false;
@@ -115,15 +116,14 @@ public class AtlasEntityType extends AtlasStructType {
             }
         }
 
-        this.superTypes                 = Collections.unmodifiableList(s);
-        this.allSuperTypes              = Collections.unmodifiableSet(allS);
-        this.allAttributes              = Collections.unmodifiableMap(allA);
-        this.uniqAttributes             = getUniqueAttributes(this.allAttributes);
-        this.subTypes                   = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
-        this.allSubTypes                = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
-        this.typeAndAllSubTypes         = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
-        this.relationshipAttributes     = new HashMap<>(); // this will be populated in resolveReferencesPhase3()
-        this.relationshipAttributesType = new HashMap<>(); // this will be populated in resolveReferencesPhase3()
+        this.superTypes             = Collections.unmodifiableList(s);
+        this.allSuperTypes          = Collections.unmodifiableSet(allS);
+        this.allAttributes          = Collections.unmodifiableMap(allA);
+        this.uniqAttributes         = getUniqueAttributes(this.allAttributes);
+        this.subTypes               = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
+        this.allSubTypes            = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
+        this.typeAndAllSubTypes     = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
+        this.relationshipAttributes = new HashMap<>(); // this will be populated in resolveReferencesPhase3()
 
         this.typeAndAllSubTypes.add(this.getTypeName());
 
@@ -193,18 +193,29 @@ public class AtlasEntityType extends AtlasStructType {
                 isInternalType = true;
             }
 
-            AtlasEntityType superType = typeRegistry.getEntityTypeByName(superTypeName);
-
-            Map<String, AtlasAttribute> superTypeRelationshipAttributes = superType.getRelationshipAttributes();
+            AtlasEntityType                          superType                       = typeRegistry.getEntityTypeByName(superTypeName);
+            Map<String, Map<String, AtlasAttribute>> superTypeRelationshipAttributes = superType.getRelationshipAttributes();
 
             if (MapUtils.isNotEmpty(superTypeRelationshipAttributes)) {
-                relationshipAttributes.putAll(superTypeRelationshipAttributes);
-            }
+                for (String attrName : superTypeRelationshipAttributes.keySet()) {
+                    Map<String, AtlasAttribute> superTypeAttributes = superTypeRelationshipAttributes.get(attrName);
+
+                    if (MapUtils.isNotEmpty(superTypeAttributes)) {
+                        Map<String, AtlasAttribute> attributes = relationshipAttributes.get(attrName);
 
-            Map<String, List<AtlasRelationshipType>> superTypeRelationshipAttributesType = superType.getRelationshipAttributesType();
+                        if (attributes == null) {
+                            attributes = new HashMap<>();
 
-            if (MapUtils.isNotEmpty(superTypeRelationshipAttributesType)) {
-                relationshipAttributesType.putAll(superTypeRelationshipAttributesType);
+                            relationshipAttributes.put(attrName, attributes);
+                        }
+
+                        for (String relationshipType : superTypeAttributes.keySet()) {
+                            if (!attributes.containsKey(relationshipType)) {
+                                attributes.put(relationshipType, superTypeAttributes.get(relationshipType));
+                            }
+                        }
+                    }
+                }
             }
         }
 
@@ -216,9 +227,11 @@ public class AtlasEntityType extends AtlasStructType {
             }
         }
 
-        for (AtlasAttribute attribute : relationshipAttributes.values()) {
-            if (attribute.isOwnedRef()) {
-                ownedRefAttributes.add(attribute);
+        for (Map<String, AtlasAttribute> attributes : relationshipAttributes.values()) {
+            for (AtlasAttribute attribute : attributes.values()) {
+                if (attribute.isOwnedRef()) {
+                    ownedRefAttributes.add(attribute);
+                }
             }
         }
 
@@ -227,7 +240,6 @@ public class AtlasEntityType extends AtlasStructType {
         typeAndAllSubTypes         = Collections.unmodifiableSet(typeAndAllSubTypes);
         typeAndAllSubTypesQryStr   = ""; // will be computed on next access
         relationshipAttributes     = Collections.unmodifiableMap(relationshipAttributes);
-        relationshipAttributesType = Collections.unmodifiableMap(relationshipAttributesType);
         ownedRefAttributes         = Collections.unmodifiableList(ownedRefAttributes);
 
         entityDef.setSubTypes(subTypes);
@@ -285,7 +297,7 @@ public class AtlasEntityType extends AtlasStructType {
         return isInternalType;
     }
 
-    public Map<String, AtlasAttribute> getRelationshipAttributes() {
+    public Map<String, Map<String, AtlasAttribute>> getRelationshipAttributes() {
         return relationshipAttributes;
     }
 
@@ -293,33 +305,40 @@ public class AtlasEntityType extends AtlasStructType {
         return ownedRefAttributes;
     }
 
-    public AtlasAttribute getRelationshipAttribute(String attributeName) {
-        return relationshipAttributes.get(attributeName);
-    }
+    public AtlasAttribute getRelationshipAttribute(String attributeName, String relationshipType) {
+        final AtlasAttribute        ret;
+        Map<String, AtlasAttribute> attributes = relationshipAttributes.get(attributeName);
 
-    // this method should be called from AtlasRelationshipType.resolveReferencesPhase2()
-    void addRelationshipAttribute(String attributeName, AtlasAttribute attribute) {
-        relationshipAttributes.put(attributeName, attribute);
+        if (MapUtils.isNotEmpty(attributes)) {
+            if (relationshipType != null && attributes.containsKey(relationshipType)) {
+                ret = attributes.get(relationshipType);
+            } else {
+                ret = attributes.values().iterator().next();
+            }
+        } else {
+            ret = null;
+        }
+
+        return ret;
     }
 
     // this method should be called from AtlasRelationshipType.resolveReferencesPhase2()
-    void addRelationshipAttributeType(String attributeName, AtlasRelationshipType relationshipType) {
-        List<AtlasRelationshipType> relationshipTypes = relationshipAttributesType.get(attributeName);
+    void addRelationshipAttribute(String attributeName, AtlasAttribute attribute, AtlasRelationshipType relationshipType) {
+        Map<String, AtlasAttribute> attributes = relationshipAttributes.get(attributeName);
+
+        if (attributes == null) {
+            attributes = new HashMap<>();
 
-        if (relationshipTypes == null) {
-            relationshipTypes = new ArrayList<>();
-            relationshipAttributesType.put(attributeName, relationshipTypes);
+            relationshipAttributes.put(attributeName, attributes);
         }
 
-        relationshipTypes.add(relationshipType);
+        attributes.put(relationshipType.getTypeName(), attribute);
     }
 
-    public List<AtlasRelationshipType> getRelationshipAttributeType(String attributeName) {
-        return relationshipAttributesType.get(attributeName);
-    }
+    public Collection<String> getAttributeRelationshipTypes(String attributeName) {
+        Map<String, AtlasAttribute> attributes = relationshipAttributes.get(attributeName);
 
-    public Map<String, List<AtlasRelationshipType>> getRelationshipAttributesType() {
-        return relationshipAttributesType;
+        return attributes != null ? attributes.keySet() : null;
     }
 
     public String getTypeAndAllSubTypesQryStr() {
@@ -342,7 +361,7 @@ public class AtlasEntityType extends AtlasStructType {
         if (allAttributes.containsKey(attrName)) {
             return allAttributes.get(attrName).getQualifiedName();
         } else if (relationshipAttributes.containsKey(attrName)) {
-            return relationshipAttributes.get(attrName).getQualifiedName();
+            return relationshipAttributes.get(attrName).values().iterator().next().getQualifiedName();
         }
 
         throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attrName, entityDef.getName());
@@ -618,9 +637,11 @@ public class AtlasEntityType extends AtlasStructType {
             if (obj instanceof AtlasEntity) {
                 AtlasEntity entityObj = (AtlasEntity) obj;
 
-                for (AtlasAttribute attribute : relationshipAttributes.values()) {
-                    Object            attributeValue = entityObj.getRelationshipAttribute(attribute.getName());
-                    AtlasAttributeDef attributeDef   = attribute.getAttributeDef();
+                for (String attributeName : relationshipAttributes.keySet()) {
+                    Object            attributeValue   = entityObj.getRelationshipAttribute(attributeName);
+                    String            relationshipType = AtlasEntityUtil.getRelationshipType(attributeValue);
+                    AtlasAttribute    attribute        = getRelationshipAttribute(attributeName, relationshipType);
+                    AtlasAttributeDef attributeDef     = attribute.getAttributeDef();
 
                     if (!isAssignableValue(attributeValue, attributeDef)) {
                         return false;
@@ -629,9 +650,11 @@ public class AtlasEntityType extends AtlasStructType {
             } else if (obj instanceof Map) {
                 Map map = AtlasTypeUtil.toRelationshipAttributes((Map) obj);
 
-                for (AtlasAttribute attribute : relationshipAttributes.values()) {
-                    Object            attributeValue = map.get(attribute.getName());
-                    AtlasAttributeDef attributeDef   = attribute.getAttributeDef();
+                for (String attributeName : relationshipAttributes.keySet()) {
+                    Object            attributeValue   = map.get(attributeName);
+                    String            relationshipType = AtlasEntityUtil.getRelationshipType(attributeValue);
+                    AtlasAttribute    attribute        = getRelationshipAttribute(attributeName, relationshipType);
+                    AtlasAttributeDef attributeDef     = attribute.getAttributeDef();
 
                     if (!isAssignableValue(attributeValue, attributeDef)) {
                         return false;
@@ -671,7 +694,8 @@ public class AtlasEntityType extends AtlasStructType {
         boolean ret = true;
 
         if (value != null) {
-            AtlasAttribute attribute = relationshipAttributes.get(attributeDef.getName());
+            String         relationshipType = AtlasEntityUtil.getRelationshipType(value);
+            AtlasAttribute attribute        = getRelationshipAttribute(attributeDef.getName(), relationshipType);
 
             if (attribute != null) {
                 AtlasType attrType = attribute.getAttributeType();
@@ -705,12 +729,14 @@ public class AtlasEntityType extends AtlasStructType {
         if (obj != null && obj instanceof AtlasEntity) {
             AtlasEntity entityObj = (AtlasEntity) obj;
 
-            for (AtlasAttribute attribute : relationshipAttributes.values()) {
-                String            attributeName = attribute.getName();
-                AtlasAttributeDef attributeDef  = attribute.getAttributeDef();
-
+            for (String attributeName : relationshipAttributes.keySet()) {
                 if (entityObj.hasRelationshipAttribute(attributeName)) {
-                    Object attributeValue = getNormalizedValue(entityObj.getRelationshipAttribute(attributeName), attributeDef);
+                    Object            attributeValue   = entityObj.getRelationshipAttribute(attributeName);
+                    String            relationshipType = AtlasEntityUtil.getRelationshipType(attributeValue);
+                    AtlasAttribute    attribute        = getRelationshipAttribute(attributeName, relationshipType);
+                    AtlasAttributeDef attributeDef     = attribute.getAttributeDef();
+
+                    attributeValue = getNormalizedValue(attributeValue, attributeDef);
 
                     entityObj.setRelationshipAttribute(attributeName, attributeValue);
                 }
@@ -720,12 +746,14 @@ public class AtlasEntityType extends AtlasStructType {
 
     public void normalizeRelationshipAttributeValues(Map<String, Object> obj) {
         if (obj != null) {
-            for (AtlasAttribute attribute : relationshipAttributes.values()) {
-                String            attributeName = attribute.getName();
-                AtlasAttributeDef attributeDef  = attribute.getAttributeDef();
-
+            for (String attributeName : relationshipAttributes.keySet()) {
                 if (obj.containsKey(attributeName)) {
-                    Object attributeValue = getNormalizedValue(obj.get(attributeName), attributeDef);
+                    Object            attributeValue   = obj.get(attributeName);
+                    String            relationshipType = AtlasEntityUtil.getRelationshipType(attributeValue);
+                    AtlasAttribute    attribute        = getRelationshipAttribute(attributeName, relationshipType);
+                    AtlasAttributeDef attributeDef     = attribute.getAttributeDef();
+
+                    attributeValue = getNormalizedValue(attributeValue, attributeDef);
 
                     obj.put(attributeName, attributeValue);
                 }
@@ -734,7 +762,8 @@ public class AtlasEntityType extends AtlasStructType {
     }
 
     private Object getNormalizedValue(Object value, AtlasAttributeDef attributeDef) {
-        AtlasAttribute attribute = relationshipAttributes.get(attributeDef.getName());
+        String         relationshipType = AtlasEntityUtil.getRelationshipType(value);
+        AtlasAttribute attribute        = getRelationshipAttribute(attributeDef.getName(), relationshipType);
 
         if (attribute != null) {
             AtlasType attrType = attribute.getAttributeType();
@@ -766,12 +795,13 @@ public class AtlasEntityType extends AtlasStructType {
             if (obj instanceof AtlasEntity) {
                 AtlasEntity entityObj = (AtlasEntity) obj;
 
-                for (AtlasAttribute attribute : relationshipAttributes.values()) {
+                for (String attributeName : relationshipAttributes.keySet()) {
+                    Object         value            = entityObj.getAttribute(attributeName);
+                    String         relationshipType = AtlasEntityUtil.getRelationshipType(value);
+                    AtlasAttribute attribute        = getRelationshipAttribute(attributeName, relationshipType);
+
                     if (attribute != null) {
-                        String    attributeName = attribute.getName();
-                        AtlasType dataType      = attribute.getAttributeType();
-                        Object    value         = entityObj.getAttribute(attributeName);
-                        String    fieldName     = objName + "." + attributeName;
+                        AtlasType dataType = attribute.getAttributeType();
 
                         if (!attribute.getAttributeDef().getIsOptional()) {
                             // if required attribute is null, check if attribute value specified in relationship
@@ -781,29 +811,28 @@ public class AtlasEntityType extends AtlasStructType {
 
                             if (value == null) {
                                 ret = false;
-                                messages.add(fieldName + ": mandatory attribute value missing in type " + getTypeName());
+                                messages.add(objName + "." + attributeName + ": mandatory attribute value missing in type " + getTypeName());
                             }
                         }
 
                         if (isValidRelationshipType(dataType) && value != null) {
-                            ret = dataType.validateValue(value, fieldName, messages) && ret;
+                            ret = dataType.validateValue(value, objName + "." + attributeName, messages) && ret;
                         }
                     }
-
                 }
             } else if (obj instanceof Map) {
                 Map attributes = AtlasTypeUtil.toStructAttributes((Map) obj);
 
-                for (AtlasAttribute attribute : relationshipAttributes.values()) {
+                for (String attributeName : relationshipAttributes.keySet()) {
+                    Object         value            = attributes.get(attributeName);
+                    String         relationshipType = AtlasEntityUtil.getRelationshipType(value);
+                    AtlasAttribute attribute        = getRelationshipAttribute(attributeName, relationshipType);
 
                     if (attribute != null) {
-                        String    attributeName = attribute.getName();
-                        AtlasType dataType      = attribute.getAttributeType();
-                        Object    value         = attributes.get(attributeName);
-                        String    fieldName     = objName + "." + attributeName;
+                        AtlasType dataType = attribute.getAttributeType();
 
                         if (isValidRelationshipType(dataType) && value != null) {
-                            ret = dataType.validateValue(value, fieldName, messages) && ret;
+                            ret = dataType.validateValue(value, objName + "." + attributeName, messages) && ret;
                         }
                     }
                 }
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java b/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
index 36e459a..304200d 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
@@ -123,9 +123,9 @@ public class AtlasRelationshipType extends AtlasStructType {
             relationshipLabel = getLegacyEdgeLabel(end2Type, endDef2.getName());
         }
 
-        addRelationshipAttributeToEndType(endDef1, end1Type, end2Type.getTypeName(), typeRegistry, relationshipLabel, relationshipDef.getRelationshipCategory());
+        addRelationshipAttributeToEndType(endDef1, end1Type, end2Type.getTypeName(), typeRegistry, relationshipLabel);
 
-        addRelationshipAttributeToEndType(endDef2, end2Type, end1Type.getTypeName(), typeRegistry, relationshipLabel, relationshipDef.getRelationshipCategory());
+        addRelationshipAttributeToEndType(endDef2, end2Type, end1Type.getTypeName(), typeRegistry, relationshipLabel);
 
         // add relationship edge direction information
         addRelationshipEdgeDirection();
@@ -138,12 +138,12 @@ public class AtlasRelationshipType extends AtlasStructType {
         if (StringUtils.equals(endDef1.getType(), endDef2.getType()) &&
                 StringUtils.equals(endDef1.getName(), endDef2.getName())) {
 
-            AtlasAttribute endAttribute = end1Type.getRelationshipAttribute(endDef1.getName());
+            AtlasAttribute endAttribute = end1Type.getRelationshipAttribute(endDef1.getName(), relationshipDef.getName());
 
             endAttribute.setRelationshipEdgeDirection(BOTH);
         } else {
-            AtlasAttribute end1Attribute = end1Type.getRelationshipAttribute(endDef1.getName());
-            AtlasAttribute end2Attribute = end2Type.getRelationshipAttribute(endDef2.getName());
+            AtlasAttribute end1Attribute = end1Type.getRelationshipAttribute(endDef1.getName(), relationshipDef.getName());
+            AtlasAttribute end2Attribute = end2Type.getRelationshipAttribute(endDef2.getName(), relationshipDef.getName());
 
             //default relationship edge direction is end1 (out) -> end2 (in)
             AtlasRelationshipEdgeDirection end1Direction = OUT;
@@ -296,7 +296,7 @@ public class AtlasRelationshipType extends AtlasStructType {
     }
 
     private void addRelationshipAttributeToEndType(AtlasRelationshipEndDef endDef, AtlasEntityType entityType, String attrTypeName,
-                                                   AtlasTypeRegistry typeRegistry, String relationshipLabel, RelationshipCategory relationshipCategory) throws AtlasBaseException {
+                                                   AtlasTypeRegistry typeRegistry, String relationshipLabel) throws AtlasBaseException {
 
         String attrName = (endDef != null) ? endDef.getName() : null;
 
@@ -321,7 +321,7 @@ public class AtlasRelationshipType extends AtlasStructType {
                 attrTypeName = AtlasBaseTypeDef.getArrayTypeName(attrTypeName);
             }
 
-            if (relationshipCategory == RelationshipCategory.COMPOSITION) {
+            if (relationshipDef.getRelationshipCategory() == RelationshipCategory.COMPOSITION) {
                 if (endDef.getIsContainer()) {
                     constraint = new AtlasConstraintDef(CONSTRAINT_TYPE_OWNED_REF);
                 } else {
@@ -344,9 +344,7 @@ public class AtlasRelationshipType extends AtlasStructType {
             attribute.setRelationshipEdgeLabel(relationshipLabel);
         }
 
-        entityType.addRelationshipAttribute(attrName, attribute);
-
-        entityType.addRelationshipAttributeType(attrName, this);
+        entityType.addRelationshipAttribute(attrName, attribute, this);
     }
 
     private String getLegacyEdgeLabel(AtlasEntityType entityType, String attributeName) {
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
index 644ed79..84c76d7 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -852,7 +852,7 @@ public class AtlasStructType extends AtlasType {
         }
 
         private String getRelationshipEdgeLabel(String relationshipLabel) {
-            return (relationshipLabel == null) ? getEdgeLabel(vertexPropertyName) : relationshipLabel;
+            return (relationshipLabel == null) ? getEdgeLabel(qualifiedName) : relationshipLabel;
         }
 
         private static String getQualifiedAttributeName(AtlasStructDef structDef, String attrName) {
diff --git a/intg/src/main/java/org/apache/atlas/utils/AtlasEntityUtil.java b/intg/src/main/java/org/apache/atlas/utils/AtlasEntityUtil.java
index 2e74536..3002217 100644
--- a/intg/src/main/java/org/apache/atlas/utils/AtlasEntityUtil.java
+++ b/intg/src/main/java/org/apache/atlas/utils/AtlasEntityUtil.java
@@ -18,11 +18,8 @@
 package org.apache.atlas.utils;
 
 
-import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
-import org.apache.atlas.type.AtlasEntityType;
-import org.apache.atlas.type.AtlasType;
-import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
+import org.apache.atlas.model.instance.AtlasRelatedObjectId;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
@@ -123,4 +120,21 @@ public class AtlasEntityUtil {
 
         return ret;
     }
+
+    public static String getRelationshipType(Object val) {
+        final String ret;
+
+        if (val instanceof AtlasRelatedObjectId) {
+            ret = ((AtlasRelatedObjectId) val).getRelationshipType();
+        } else if (val instanceof Map) {
+            Object relTypeName = ((Map) val).get(AtlasRelatedObjectId.KEY_RELATIONSHIP_TYPE);
+
+            ret = relTypeName != null ? relTypeName.toString() : null;
+        } else {
+            ret = null;
+        }
+
+        return ret;
+    }
+
 }
diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java b/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
index 819dfe5..1075395 100644
--- a/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
+++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
@@ -140,7 +140,7 @@ public class TestAtlasRelationshipType {
 
     @Test(dependsOnMethods = "createTypesAndRelationships")
     public void testRelationshipAttributes() throws Exception {
-        Map<String, AtlasAttribute> employeeRelationAttrs = getRelationAttrsForType(EMPLOYEE_TYPE);
+        Map<String, Map<String, AtlasAttribute>> employeeRelationAttrs = getRelationAttrsForType(EMPLOYEE_TYPE);
 
         Assert.assertNotNull(employeeRelationAttrs);
         Assert.assertEquals(employeeRelationAttrs.size(), 2);
@@ -148,28 +148,28 @@ public class TestAtlasRelationshipType {
         Assert.assertTrue(employeeRelationAttrs.containsKey("department"));
         Assert.assertTrue(employeeRelationAttrs.containsKey("address"));
 
-        AtlasAttribute deptAttr = employeeRelationAttrs.get("department");
+        AtlasAttribute deptAttr = employeeRelationAttrs.get("department").values().iterator().next();
         Assert.assertEquals(deptAttr.getTypeName(), DEPARTMENT_TYPE);
 
-        AtlasAttribute addrAttr = employeeRelationAttrs.get("address");
+        AtlasAttribute addrAttr = employeeRelationAttrs.get("address").values().iterator().next();
         Assert.assertEquals(addrAttr.getTypeName(), ADDRESS_TYPE);
 
-        Map<String, AtlasAttribute> deptRelationAttrs = getRelationAttrsForType(DEPARTMENT_TYPE);
+        Map<String, Map<String, AtlasAttribute>> deptRelationAttrs = getRelationAttrsForType(DEPARTMENT_TYPE);
 
         Assert.assertNotNull(deptRelationAttrs);
         Assert.assertEquals(deptRelationAttrs.size(), 1);
         Assert.assertTrue(deptRelationAttrs.containsKey("employees"));
 
-        AtlasAttribute employeesAttr = deptRelationAttrs.get("employees");
+        AtlasAttribute employeesAttr = deptRelationAttrs.get("employees").values().iterator().next();
         Assert.assertEquals(employeesAttr.getTypeName(),AtlasBaseTypeDef.getArrayTypeName(EMPLOYEE_TYPE));
 
-        Map<String, AtlasAttribute> addressRelationAttrs = getRelationAttrsForType(ADDRESS_TYPE);
+        Map<String, Map<String, AtlasAttribute>> addressRelationAttrs = getRelationAttrsForType(ADDRESS_TYPE);
 
         Assert.assertNotNull(addressRelationAttrs);
         Assert.assertEquals(addressRelationAttrs.size(), 1);
         Assert.assertTrue(addressRelationAttrs.containsKey("employees"));
 
-        AtlasAttribute employeesAttr1 = addressRelationAttrs.get("employees");
+        AtlasAttribute employeesAttr1 = addressRelationAttrs.get("employees").values().iterator().next();
         Assert.assertEquals(employeesAttr1.getTypeName(),AtlasBaseTypeDef.getArrayTypeName(EMPLOYEE_TYPE));
     }
 
@@ -182,8 +182,8 @@ public class TestAtlasRelationshipType {
 
         createType(employeePhoneRelationDef);
 
-        Map<String, AtlasAttribute> employeeRelationshipAttrs = getRelationAttrsForType(EMPLOYEE_TYPE);
-        Map<String, AtlasAttribute> employeeAttrs             = getAttrsForType(EMPLOYEE_TYPE);
+        Map<String, Map<String, AtlasAttribute>> employeeRelationshipAttrs = getRelationAttrsForType(EMPLOYEE_TYPE);
+        Map<String, AtlasAttribute>              employeeAttrs             = getAttrsForType(EMPLOYEE_TYPE);
 
         // validate if phone_no exists in both relationAttributes and attributes
         Assert.assertTrue(employeeRelationshipAttrs.containsKey("phone_no"));
@@ -245,7 +245,7 @@ public class TestAtlasRelationshipType {
         return typeName + " description";
     }
 
-    private Map<String, AtlasAttribute> getRelationAttrsForType(String typeName) {
+    private Map<String, Map<String, AtlasAttribute>> getRelationAttrsForType(String typeName) {
         return typeRegistry.getEntityTypeByName(typeName).getRelationshipAttributes();
     }
 
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
index 2378d6b..9df360c 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
@@ -81,7 +81,6 @@ import static org.apache.atlas.model.TypeCategory.MAP;
 import static org.apache.atlas.model.TypeCategory.OBJECT_ID_TYPE;
 import static org.apache.atlas.model.instance.AtlasEntity.Status.ACTIVE;
 import static org.apache.atlas.model.instance.AtlasEntity.Status.DELETED;
-import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX;
 import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.*;
 
 @Component
@@ -539,7 +538,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
 
         if (attribute != null) {
             if (isRelationshipAttribute(attribute)) {
-                relation = EDGE_LABEL_PREFIX + attribute.getQualifiedName();
+                relation = attribute.getRelationshipEdgeLabel();
             } else {
                 throw new AtlasBaseException(AtlasErrorCode.INVALID_RELATIONSHIP_ATTRIBUTE, relation, attribute.getTypeName());
             }
diff --git a/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java b/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
index b4542b7..393ce38 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
@@ -31,6 +31,7 @@ import org.apache.atlas.repository.graphdb.AtlasGraph;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
+import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
 import org.apache.atlas.type.AtlasClassificationType;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasStructType;
@@ -239,7 +240,7 @@ public class SearchContext {
     private List<AtlasVertex> getAssignedEntities(AtlasVertex glossaryTerm) {
         List<AtlasVertex>   ret      = new ArrayList<>();
         AtlasEntityType     termType = getTermEntityType();
-        AtlasAttribute      attr     = termType.getRelationshipAttribute(TermSearchProcessor.ATLAS_GLOSSARY_TERM_ATTR_ASSIGNED_ENTITIES);
+        AtlasAttribute      attr     = termType.getRelationshipAttribute(TermSearchProcessor.ATLAS_GLOSSARY_TERM_ATTR_ASSIGNED_ENTITIES, EntityGraphRetriever.TERM_RELATION_NAME);
         Iterator<AtlasEdge> edges    = GraphHelper.getEdgesForLabel(glossaryTerm, attr.getRelationshipEdgeLabel(), attr.getRelationshipEdgeDirection());
 
         boolean excludeDeletedEntities = searchParameters.getExcludeDeletedEntities();
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
index 97e3e25..f3ebc43 100755
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
@@ -31,7 +31,6 @@ import org.apache.atlas.model.instance.AtlasEntity.Status;
 import org.apache.atlas.model.instance.AtlasEntityHeader;
 import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.model.instance.AtlasRelationship;
-import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.repository.graphdb.AtlasVertexQuery;
 import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
 import org.apache.atlas.type.AtlasArrayType;
@@ -51,7 +50,6 @@ import org.apache.atlas.repository.graphdb.AtlasGraph;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.type.AtlasEntityType;
-import org.apache.atlas.type.AtlasRelationshipType;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.exception.EntityNotFoundException;
 import org.apache.atlas.util.AttributeValueMap;
@@ -1058,7 +1056,7 @@ public final class GraphHelper {
     }
 
     public static String getEdgeLabel(AtlasAttribute aInfo) throws AtlasException {
-        return GraphHelper.EDGE_LABEL_PREFIX + aInfo.getQualifiedName();
+        return aInfo.getRelationshipEdgeLabel();
     }
 
     public static Id getIdFromVertex(String dataTypeName, AtlasVertex vertex) {
@@ -1774,40 +1772,27 @@ public final class GraphHelper {
      * resolve by comparing all incoming edges typename with relationDefs name returned for an attribute
      * to pick the right relationshipDef name
      */
-    public String getRelationshipDefName(AtlasVertex entityVertex, AtlasEntityType entityType, String attributeName) {
-        AtlasRelationshipDef relationshipDef = getRelationshipDef(entityVertex, entityType, attributeName);
+    public String getRelationshipTypeName(AtlasVertex entityVertex, AtlasEntityType entityType, String attributeName) {
+        String             ret               = null;
+        Collection<String> relationshipTypes = entityType.getAttributeRelationshipTypes(attributeName);
 
-        return (relationshipDef != null) ? relationshipDef.getName() : null;
-    }
-
-    public AtlasRelationshipDef getRelationshipDef(AtlasVertex entityVertex, AtlasEntityType entityType, String attributeName) {
-        List<AtlasRelationshipType> relationshipTypes = entityType.getRelationshipAttributeType(attributeName);
-        AtlasRelationshipDef        ret               = null;
-
-        if (relationshipTypes.size() > 1) {
+        if (CollectionUtils.isNotEmpty(relationshipTypes)) {
             Iterator<AtlasEdge> iter = entityVertex.getEdges(AtlasEdgeDirection.IN).iterator();
 
             while (iter.hasNext() && ret == null) {
                 String edgeTypeName = AtlasGraphUtilsV2.getTypeName(iter.next());
 
-                for (AtlasRelationshipType relationType : relationshipTypes) {
-                    AtlasRelationshipDef relationshipDef = relationType.getRelationshipDef();
+                if (relationshipTypes.contains(edgeTypeName)) {
+                    ret = edgeTypeName;
 
-                    if (StringUtils.equals(edgeTypeName, relationshipDef.getName())) {
-                        ret = relationshipDef;
-
-                        break;
-                    }
+                    break;
                 }
             }
 
             if (ret == null) {
-                ret = relationshipTypes.get(0).getRelationshipDef();
+                //relationshipTypes will have at least one relationshipDef
+                ret = relationshipTypes.iterator().next();
             }
-
-        } else {
-            //relationshipTypes will have at least one relationshipDef
-            ret = relationshipTypes.get(0).getRelationshipDef();
         }
 
         return ret;
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java
index 5632520..62298f9 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java
@@ -620,7 +620,7 @@ public class ExportService {
         } else if (type instanceof AtlasEnumType) {
             addEnumType((AtlasEnumType)type, context);
         } else if (type instanceof AtlasRelationshipType) {
-            addRelationshipType((AtlasRelationshipType)type, context);
+            addRelationshipType(type.getTypeName(), context);
         }
     }
 
@@ -667,13 +667,17 @@ public class ExportService {
         }
     }
 
-    private void addRelationshipType(AtlasRelationshipType relationshipType, ExportContext context) {
-        if (!context.relationshipTypes.contains(relationshipType.getTypeName())) {
-            context.relationshipTypes.add(relationshipType.getTypeName());
+    private void addRelationshipType(String relationshipTypeName, ExportContext context) {
+        if (!context.relationshipTypes.contains(relationshipTypeName)) {
+            AtlasRelationshipType relationshipType = typeRegistry.getRelationshipTypeByName(relationshipTypeName);
 
-            addAttributeTypes(relationshipType, context);
-            addEntityType(relationshipType.getEnd1Type(), context);
-            addEntityType(relationshipType.getEnd2Type(), context);
+            if (relationshipType != null) {
+                context.relationshipTypes.add(relationshipTypeName);
+
+                addAttributeTypes(relationshipType, context);
+                addEntityType(relationshipType.getEnd1Type(), context);
+                addEntityType(relationshipType.getEnd2Type(), context);
+            }
         }
     }
 
@@ -684,8 +688,8 @@ public class ExportService {
     }
 
     private void addRelationshipTypes(AtlasEntityType entityType, ExportContext context) {
-        for (List<AtlasRelationshipType> relationshipTypes : entityType.getRelationshipAttributesType().values()) {
-            for (AtlasRelationshipType relationshipType : relationshipTypes) {
+        for (Map.Entry<String, Map<String, AtlasAttribute>> entry : entityType.getRelationshipAttributes().entrySet()) {
+            for (String relationshipType : entry.getValue().keySet()) {
                 addRelationshipType(relationshipType, context);
             }
         }
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java
index f528b17..b513996 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java
@@ -36,7 +36,7 @@ import org.apache.commons.collections.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.List;
+import java.util.Map;
 
 class ExportTypeProcessor {
     private static final Logger LOG = LoggerFactory.getLogger(ExportTypeProcessor.class);
@@ -110,7 +110,7 @@ class ExportTypeProcessor {
         } else if (type instanceof AtlasEnumType) {
             addEnumType((AtlasEnumType)type, context);
         } else if (type instanceof AtlasRelationshipType) {
-            addRelationshipType((AtlasRelationshipType)type, context);
+            addRelationshipType(type.getTypeName(), context);
         }
     }
 
@@ -157,13 +157,17 @@ class ExportTypeProcessor {
         }
     }
 
-    private void addRelationshipType(AtlasRelationshipType relationshipType, ExportService.ExportContext context) {
-        if (!context.relationshipTypes.contains(relationshipType.getTypeName())) {
-            context.relationshipTypes.add(relationshipType.getTypeName());
+    private void addRelationshipType(String relationshipTypeName, ExportService.ExportContext context) {
+        if (!context.relationshipTypes.contains(relationshipTypeName)) {
+            AtlasRelationshipType relationshipType = typeRegistry.getRelationshipTypeByName(relationshipTypeName);
 
-            addAttributeTypes(relationshipType, context);
-            addEntityType(relationshipType.getEnd1Type(), context);
-            addEntityType(relationshipType.getEnd2Type(), context);
+            if (relationshipType != null) {
+                context.relationshipTypes.add(relationshipTypeName);
+
+                addAttributeTypes(relationshipType, context);
+                addEntityType(relationshipType.getEnd1Type(), context);
+                addEntityType(relationshipType.getEnd2Type(), context);
+            }
         }
     }
 
@@ -174,8 +178,8 @@ class ExportTypeProcessor {
     }
 
     private void addRelationshipTypes(AtlasEntityType entityType, ExportService.ExportContext context) {
-        for (List<AtlasRelationshipType> relationshipTypes : entityType.getRelationshipAttributesType().values()) {
-            for (AtlasRelationshipType relationshipType : relationshipTypes) {
+        for (Map.Entry<String, Map<String, AtlasStructType.AtlasAttribute>> entry : entityType.getRelationshipAttributes().entrySet()) {
+            for (String relationshipType : entry.getValue().keySet()) {
                 addRelationshipType(relationshipType, context);
             }
         }
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityGraphDiscoveryV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityGraphDiscoveryV2.java
index 23dc83a..4ff4206 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityGraphDiscoveryV2.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityGraphDiscoveryV2.java
@@ -36,6 +36,7 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.type.AtlasTypeUtil;
+import org.apache.atlas.utils.AtlasEntityUtil;
 import org.apache.atlas.utils.AtlasPerfMetrics.MetricRecorder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -330,16 +331,23 @@ public class AtlasEntityGraphDiscoveryV2 implements EntityGraphDiscovery {
     }
 
     private void visitRelationships(AtlasEntityType entityType, AtlasEntity entity, List<String> visitedAttributes) throws AtlasBaseException {
-        for (AtlasAttribute attribute : entityType.getRelationshipAttributes().values()) {
-            String attrName = attribute.getName();
+        for (String attrName : entityType.getRelationshipAttributes().keySet()) {
 
             // if attribute is not in 'relationshipAttributes', try 'attributes'
             if (entity.hasRelationshipAttribute(attrName)) {
-                visitAttribute(attribute.getAttributeType(), entity.getRelationshipAttribute(attrName));
+                Object         attrVal          = entity.getRelationshipAttribute(attrName);
+                String         relationshipType = AtlasEntityUtil.getRelationshipType(attrVal);
+                AtlasAttribute attribute        = entityType.getRelationshipAttribute(attrName, relationshipType);
+
+                visitAttribute(attribute.getAttributeType(), attrVal);
 
                 visitedAttributes.add(attrName);
             } else if (entity.hasAttribute(attrName)) {
-                visitAttribute(attribute.getAttributeType(), entity.getAttribute(attrName));
+                Object         attrVal          = entity.getAttribute(attrName);
+                String         relationshipType = AtlasEntityUtil.getRelationshipType(attrVal);
+                AtlasAttribute attribute        = entityType.getRelationshipAttribute(attrName, relationshipType);
+
+                visitAttribute(attribute.getAttributeType(), attrVal);
 
                 visitedAttributes.add(attrName);
             }
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
index 18eb337..bd3a62a 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
@@ -41,6 +41,7 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.type.AtlasTypeUtil;
+import org.apache.atlas.utils.AtlasEntityUtil;
 import org.apache.atlas.utils.AtlasPerfMetrics.MetricRecorder;
 import org.apache.atlas.utils.AtlasPerfTracer;
 import org.apache.commons.collections.CollectionUtils;
@@ -760,13 +761,15 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
                     }
 
                     if (!hasUpdates && MapUtils.isNotEmpty(entity.getRelationshipAttributes())) { // check of relationsship-attribute value change
-                        for (AtlasAttribute attribute : entityType.getRelationshipAttributes().values()) {
-                            if (!entity.getRelationshipAttributes().containsKey(attribute.getName())) {  // if value is not provided, current value will not be updated
+                        for (String attributeName : entityType.getRelationshipAttributes().keySet()) {
+                            if (!entity.getRelationshipAttributes().containsKey(attributeName)) {  // if value is not provided, current value will not be updated
                                 continue;
                             }
 
-                            Object newVal  = entity.getRelationshipAttribute(attribute.getName());
-                            Object currVal = entityRetriever.getEntityAttribute(vertex, attribute);
+                            Object         newVal           = entity.getRelationshipAttribute(attributeName);
+                            String         relationshipType = AtlasEntityUtil.getRelationshipType(newVal);
+                            AtlasAttribute attribute        = entityType.getRelationshipAttribute(attributeName, relationshipType);
+                            Object         currVal          = entityRetriever.getEntityAttribute(vertex, attribute);
 
                             if (!attribute.getAttributeType().areEqualValues(currVal, newVal, context.getGuidAssignments())) {
                                 hasUpdates = true;
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasGraphUtilsV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasGraphUtilsV2.java
index 798b362..8f4baa1 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasGraphUtilsV2.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasGraphUtilsV2.java
@@ -126,10 +126,6 @@ public class AtlasGraphUtilsV2 {
         return GraphHelper.EDGE_LABEL_PREFIX + property;
     }
 
-    public static String getAttributeEdgeLabel(AtlasStructType fromType, String attributeName) throws AtlasBaseException {
-        return getEdgeLabel(getQualifiedAttributePropertyKey(fromType, attributeName));
-    }
-
     public static String getQualifiedAttributePropertyKey(AtlasStructType fromType, String attributeName) throws AtlasBaseException {
         switch (fromType.getTypeCategory()) {
          case ENTITY:
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipDefStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipDefStoreV2.java
index af89df2..bfee34e 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipDefStoreV2.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipDefStoreV2.java
@@ -459,6 +459,7 @@ public class AtlasRelationshipDefStoreV2 extends AtlasAbstractDefStoreV2<AtlasRe
 
         // Update RelationshipCategory
         vertex.setProperty(Constants.RELATIONSHIPTYPE_CATEGORY_KEY, relationshipCategory);
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_LABEL_KEY, relationshipDef.getRelationshipLabel());
 
         vertex.setProperty(Constants.RELATIONSHIPTYPE_LABEL_KEY, relationshipDef.getRelationshipLabel());
 
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java
index 47a7546..555288f 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java
@@ -810,12 +810,11 @@ public class AtlasRelationshipStoreV2 implements AtlasRelationshipStore {
         if (fromVertexTypes.contains(endDef1.getType()) && toVertexTypes.contains(endDef2.getType())) {
             String attributeName = endDef1.getName();
 
-            attribute = relationshipType.getEnd1Type().getRelationshipAttribute(attributeName);
-
+            attribute = relationshipType.getEnd1Type().getRelationshipAttribute(attributeName, relationshipTypeName);
         } else if (fromVertexTypes.contains(endDef2.getType()) && toVertexTypes.contains(endDef1.getType())) {
             String attributeName = endDef2.getName();
 
-            attribute = relationshipType.getEnd2Type().getRelationshipAttribute(attributeName);
+            attribute = relationshipType.getEnd2Type().getRelationshipAttribute(attributeName, relationshipTypeName);
         }
 
         if (attribute != null) {
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
index baaca0b..601e5f8 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
@@ -339,17 +339,21 @@ public class EntityGraphMapper {
             MetricRecorder metric = RequestContext.get().startMetricRecord("mapRelationshipAttributes");
 
             if (op.equals(CREATE)) {
-                for (AtlasAttribute attribute : entityType.getRelationshipAttributes().values()) {
-                    Object attrValue = entity.getRelationshipAttribute(attribute.getName());
+                for (String attrName : entityType.getRelationshipAttributes().keySet()) {
+                    Object         attrValue    = entity.getRelationshipAttribute(attrName);
+                    String         relationType = AtlasEntityUtil.getRelationshipType(attrValue);
+                    AtlasAttribute attribute    = entityType.getRelationshipAttribute(attrName, relationType);
 
                     mapAttribute(attribute, attrValue, vertex, op, context);
                 }
 
             } else if (op.equals(UPDATE)) {
                 // relationship attributes mapping
-                for (AtlasAttribute attribute : entityType.getRelationshipAttributes().values()) {
-                    if (attribute != null && entity.hasRelationshipAttribute(attribute.getName())) {
-                        Object attrValue = entity.getRelationshipAttribute(attribute.getName());
+                for (String attrName : entityType.getRelationshipAttributes().keySet()) {
+                    if (entity.hasRelationshipAttribute(attrName)) {
+                        Object         attrValue    = entity.getRelationshipAttribute(attrName);
+                        String         relationType = AtlasEntityUtil.getRelationshipType(attrValue);
+                        AtlasAttribute attribute    = entityType.getRelationshipAttribute(attrName, relationType);
 
                         mapAttribute(attribute, attrValue, vertex, op, context);
                     }
@@ -599,7 +603,7 @@ public class EntityGraphMapper {
             AtlasEntityType entityType = (AtlasEntityType) inverseAttributeType;
 
             if (entityType.hasRelationshipAttribute(inverseAttributeName)) {
-                String relationshipName = graphHelper.getRelationshipDefName(inverseVertex, entityType, inverseAttributeName);
+                String relationshipName = graphHelper.getRelationshipTypeName(inverseVertex, entityType, inverseAttributeName);
 
                 ret = getOrCreateRelationship(inverseVertex, vertex, relationshipName, relationshipAttributes);
 
@@ -843,7 +847,7 @@ public class EntityGraphMapper {
                     ret = updateRelationship(ctx.getCurrentEdge(), entityVertex, attributeVertex, edgeDirection, relationshipAttributes);
 
                 } else {
-                    String      relationshipName = graphHelper.getRelationshipDefName(entityVertex, entityType, attributeName);
+                    String      relationshipName = graphHelper.getRelationshipTypeName(entityVertex, entityType, attributeName);
                     AtlasVertex fromVertex;
                     AtlasVertex toVertex;
 
@@ -1900,8 +1904,7 @@ public class EntityGraphMapper {
     // move/remove relationship-attributes present in 'attributes'
     private static void compactAttributes(AtlasEntity entity, AtlasEntityType entityType) {
         if (entity != null) {
-            for (AtlasAttribute attribute : entityType.getRelationshipAttributes().values()) {
-                String attrName = attribute.getName();
+            for (String attrName : entityType.getRelationshipAttributes().keySet()) {
 
                 if (entity.hasAttribute(attrName)) {
                     Object attrValue = entity.getAttribute(attrName);
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
index e2b7433..dd185be 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
@@ -100,8 +100,8 @@ import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelation
 public class EntityGraphRetriever {
     private static final Logger LOG = LoggerFactory.getLogger(EntityGraphRetriever.class);
 
-    private static final String TERM_RELATION_NAME = "AtlasGlossarySemanticAssignment";
     private static final String GLOSSARY_TERM_DISPLAY_NAME_ATTR = "AtlasGlossaryTerm.name";
+    public  static final String TERM_RELATION_NAME              = "AtlasGlossarySemanticAssignment";
 
     public static final String NAME           = "name";
     public static final String DISPLAY_NAME   = "displayName";
@@ -655,7 +655,7 @@ public class EntityGraphRetriever {
     private Object mapVertexToAttribute(AtlasVertex entityVertex, AtlasAttribute attribute, AtlasEntityExtInfo entityExtInfo, final boolean isMinExtInfo) throws AtlasBaseException {
         Object    ret                = null;
         AtlasType attrType           = attribute.getAttributeType();
-        String    edgeLabel          = EDGE_LABEL_PREFIX + attribute.getQualifiedName();
+        String    edgeLabel          = attribute.getRelationshipEdgeLabel();
         boolean   isOwnedAttribute   = attribute.isOwnedRef();
         AtlasRelationshipEdgeDirection edgeDirection = attribute.getRelationshipEdgeDirection();
 
@@ -997,30 +997,32 @@ public class EntityGraphRetriever {
             throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, entity.getTypeName());
         }
 
-        for (AtlasAttribute attribute : entityType.getRelationshipAttributes().values()) {
-            Object attrValue = mapVertexToRelationshipAttribute(entityVertex, entityType, attribute);
+        for (String attributeName : entityType.getRelationshipAttributes().keySet()) {
+            Object attrValue = mapVertexToRelationshipAttribute(entityVertex, entityType, attributeName);
 
-            entity.setRelationshipAttribute(attribute.getName(), attrValue);
+            entity.setRelationshipAttribute(attributeName, attrValue);
         }
     }
 
-    private Object mapVertexToRelationshipAttribute(AtlasVertex entityVertex, AtlasEntityType entityType, AtlasAttribute attribute) throws AtlasBaseException {
-        Object               ret             = null;
-        AtlasRelationshipDef relationshipDef = graphHelper.getRelationshipDef(entityVertex, entityType, attribute.getName());
+    private Object mapVertexToRelationshipAttribute(AtlasVertex entityVertex, AtlasEntityType entityType, String attributeName) throws AtlasBaseException {
+        Object                ret                  = null;
+        String                relationshipTypeName = graphHelper.getRelationshipTypeName(entityVertex, entityType, attributeName);
+        AtlasRelationshipType relationshipType     = relationshipTypeName != null ? typeRegistry.getRelationshipTypeByName(relationshipTypeName) : null;
 
-        if (relationshipDef == null) {
+        if (relationshipType == null) {
             throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_INVALID, "relationshipDef is null");
         }
 
+        AtlasRelationshipDef    relationshipDef = relationshipType.getRelationshipDef();
         AtlasRelationshipEndDef endDef1         = relationshipDef.getEndDef1();
         AtlasRelationshipEndDef endDef2         = relationshipDef.getEndDef2();
         AtlasEntityType         endDef1Type     = typeRegistry.getEntityTypeByName(endDef1.getType());
         AtlasEntityType         endDef2Type     = typeRegistry.getEntityTypeByName(endDef2.getType());
         AtlasRelationshipEndDef attributeEndDef = null;
 
-        if (endDef1Type.isTypeOrSuperTypeOf(entityType.getTypeName()) && StringUtils.equals(endDef1.getName(), attribute.getName())) {
+        if (endDef1Type.isTypeOrSuperTypeOf(entityType.getTypeName()) && StringUtils.equals(endDef1.getName(), attributeName)) {
             attributeEndDef = endDef1;
-        } else if (endDef2Type.isTypeOrSuperTypeOf(entityType.getTypeName()) && StringUtils.equals(endDef2.getName(), attribute.getName())) {
+        } else if (endDef2Type.isTypeOrSuperTypeOf(entityType.getTypeName()) && StringUtils.equals(endDef2.getName(), attributeName)) {
             attributeEndDef = endDef2;
         }
 
@@ -1030,12 +1032,12 @@ public class EntityGraphRetriever {
 
         switch (attributeEndDef.getCardinality()) {
             case SINGLE:
-                ret = mapRelatedVertexToObjectId(entityVertex, attribute);
+                ret = mapRelatedVertexToObjectId(entityVertex, entityType.getRelationshipAttribute(attributeName, relationshipTypeName));
                 break;
 
             case LIST:
             case SET:
-                ret = mapRelationshipArrayAttribute(entityVertex, attribute);
+                ret = mapRelationshipArrayAttribute(entityVertex, entityType.getRelationshipAttribute(attributeName, relationshipTypeName));
                 break;
         }