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 2017/02/04 00:33:05 UTC

[1/3] incubator-atlas git commit: ATLAS-1522: V2 entity API changes to accept only AtlasObjectId for child references

Repository: incubator-atlas
Updated Branches:
  refs/heads/master 02cf8c488 -> d8c2a10e0


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
index aa209f9..d82e5ba 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
@@ -35,6 +35,7 @@ import org.apache.atlas.typesystem.IStruct;
 import org.apache.atlas.typesystem.ITypedReferenceableInstance;
 import org.apache.atlas.typesystem.ITypedStruct;
 import org.apache.atlas.typesystem.Referenceable;
+import org.apache.atlas.web.adapters.AtlasFormatConverter;
 import org.apache.atlas.web.adapters.AtlasInstanceRestAdapters;
 import org.apache.atlas.web.util.Servlets;
 import org.apache.commons.lang3.StringUtils;
@@ -47,6 +48,7 @@ import javax.ws.rs.*;
 import javax.ws.rs.core.MediaType;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import static org.apache.atlas.web.adapters.AtlasInstanceRestAdapters.toAtlasBaseException;
 import static org.apache.atlas.web.adapters.AtlasInstanceRestAdapters.toEntityMutationResponse;
@@ -74,45 +76,6 @@ public class EntityREST {
     }
 
     /**
-     * Create or Update an entity if it  already exists
-     *
-     * @param entity The updated entity
-     * @return
-     */
-    @POST
-    @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
-    @Produces(Servlets.JSON_MEDIA_TYPE)
-    public EntityMutationResponse createOrUpdate(final AtlasEntity entity) throws AtlasBaseException {
-        EntityMutationResponse response = null;
-        ITypedReferenceableInstance[] entitiesInOldFormat = restAdapters.getITypedReferenceables(new ArrayList<AtlasEntity>() {{ add(entity); }});
-
-        try {
-            final AtlasClient.EntityResult result = metadataService.updateEntities(entitiesInOldFormat);
-            response = toEntityMutationResponse(result);
-        } catch (AtlasException e) {
-            LOG.error("Exception while getting a typed reference for the entity ", e);
-            throw AtlasInstanceRestAdapters.toAtlasBaseException(e);
-        }
-        return response;
-    }
-
-    /**
-     * Complete Update of an entity identified by its GUID
-     *
-     * @param guid
-     * @param entity The updated entity
-     * @return
-     */
-    @PUT
-    @Path("guid/{guid}")
-    @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
-    @Produces(Servlets.JSON_MEDIA_TYPE)
-    public EntityMutationResponse updateByGuid(@PathParam("guid") String guid, AtlasEntity entity, @DefaultValue("false") @QueryParam("partialUpdate") boolean partialUpdate) throws AtlasBaseException {
-        return createOrUpdate(entity);
-    }
-
-
-    /**
      * Fetch the complete definition of an entity given its GUID.
      *
      * @param guid GUID for the entity
@@ -120,10 +83,14 @@ public class EntityREST {
     @GET
     @Path("/guid/{guid}")
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public AtlasEntity getById(@PathParam("guid") String guid) throws AtlasBaseException {
+    public List<AtlasEntityWithAssociations> getById(@PathParam("guid") String guid) throws AtlasBaseException {
+        List<AtlasEntityWithAssociations> entityList = new ArrayList<>();
+
         try {
             ITypedReferenceableInstance ref = metadataService.getEntityDefinition(guid);
-            return restAdapters.getAtlasEntity(ref);
+            Map<String, AtlasEntityWithAssociations> entityRet = restAdapters.getAtlasEntity(ref);
+            entityList.addAll(entityRet.values());
+            return entityList;
         } catch (AtlasException e) {
             throw toAtlasBaseException(e);
         }
@@ -138,10 +105,14 @@ public class EntityREST {
     @GET
     @Path("/guid/{guid}/associations")
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public AtlasEntityWithAssociations getWithAssociationsByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
+    public List<AtlasEntityWithAssociations> getWithAssociationsByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
+
+        List<AtlasEntityWithAssociations> entityList = new ArrayList<>();
         try {
             ITypedReferenceableInstance ref = metadataService.getEntityDefinition(guid);
-            return restAdapters.getAtlasEntity(ref);
+            Map<String, AtlasEntityWithAssociations> entityRet = restAdapters.getAtlasEntity(ref);
+            entityList.addAll(entityRet.values());
+            return entityList;
         } catch (AtlasException e) {
             throw toAtlasBaseException(e);
         }
@@ -190,7 +161,9 @@ public class EntityREST {
         AtlasEntityType type = (AtlasEntityType) validateType(entityType, TypeCategory.ENTITY);
         validateUniqueAttribute(type, attribute);
 
-        Referenceable ref = restAdapters.getReferenceable(entity);
+        AtlasFormatConverter.ConverterContext ctx = new AtlasFormatConverter.ConverterContext();
+        ctx.addEntity(entity);
+        Referenceable ref = restAdapters.getReferenceable(entity, ctx);
         AtlasClient.EntityResult result = metadataService.updateEntityByUniqueAttribute(entityType, attribute, value, ref);
         return toEntityMutationResponse(result);
     }
@@ -220,19 +193,23 @@ public class EntityREST {
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
     @Path("/uniqueAttribute/type/{typeName}/attribute/{attrName}")
-    public AtlasEntity getByUniqueAttribute(@PathParam("typeName") String entityType,
+    public List<AtlasEntityWithAssociations> getByUniqueAttribute(@PathParam("typeName") String entityType,
         @PathParam("attrName") String attribute,
         @QueryParam("value") String value) throws AtlasBaseException {
 
+        List<AtlasEntityWithAssociations> entityList = new ArrayList<>();
         AtlasEntityType type = (AtlasEntityType) validateType(entityType, TypeCategory.ENTITY);
         validateUniqueAttribute(type, attribute);
 
         try {
             final ITypedReferenceableInstance entityDefinitionReference = metadataService.getEntityDefinitionReference(entityType, attribute, value);
-            return restAdapters.getAtlasEntity(entityDefinitionReference);
+            Map<String, AtlasEntityWithAssociations> entityRet = restAdapters.getAtlasEntity(entityDefinitionReference);
+            entityList.addAll(entityRet.values());
         } catch (AtlasException e) {
             throw toAtlasBaseException(e);
         }
+
+        return entityList;
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
index cfe9909..9957f42 100644
--- a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
+++ b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
@@ -26,6 +26,7 @@ import org.apache.atlas.TestUtilsV2;
 import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.model.instance.AtlasStruct;
 import org.apache.atlas.model.instance.ClassificationAssociateRequest;
 import org.apache.atlas.model.instance.EntityMutationResponse;
@@ -68,6 +69,10 @@ public class TestEntitiesREST {
 
     private List<String> createdGuids = new ArrayList<>();
 
+    private Map<String, AtlasEntity> dbEntityMap;
+
+    private Map<String, AtlasEntity> tableEntityMap;
+
     private AtlasEntity dbEntity;
 
     private AtlasEntity tableEntity;
@@ -78,9 +83,12 @@ public class TestEntitiesREST {
     public void setUp() throws Exception {
         AtlasTypesDef typesDef = TestUtilsV2.defineHiveTypes();
         typeStore.createTypesDef(typesDef);
-        dbEntity = TestUtilsV2.createDBEntity();
+        dbEntityMap = TestUtilsV2.createDBEntity();
+        dbEntity = dbEntityMap.values().iterator().next();
+
+        tableEntityMap = TestUtilsV2.createTableEntity(dbEntity.getGuid());
+        tableEntity = tableEntityMap.values().iterator().next();
 
-        tableEntity = TestUtilsV2.createTableEntity(dbEntity.getGuid());
         final AtlasEntity colEntity = TestUtilsV2.createColumnEntity(tableEntity.getGuid());
         columns = new ArrayList<AtlasEntity>() {{ add(colEntity); }};
         tableEntity.setAttribute("columns", columns);
@@ -98,9 +106,9 @@ public class TestEntitiesREST {
 
     @Test
     public void testCreateOrUpdateEntities() throws Exception {
-        List<AtlasEntity> entities = new ArrayList<AtlasEntity>();
-        entities.add(dbEntity);
-        entities.add(tableEntity);
+        Map<String, AtlasEntity> entities = new HashMap<>();
+        entities.put(dbEntity.getGuid(), dbEntity);
+        entities.put(tableEntity.getGuid(), tableEntity);
 
         EntityMutationResponse response = entitiesREST.createOrUpdate(entities);
         List<AtlasEntityHeader> guids = response.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE);
@@ -129,9 +137,12 @@ public class TestEntitiesREST {
     public void testUpdateWithSerializedEntities() throws  Exception {
         //Check with serialization and deserialization of entity attributes for the case
         // where attributes which are de-serialized into a map
-        AtlasEntity dbEntity = TestUtilsV2.createDBEntity();
+        Map<String, AtlasEntity> dbEntityMap = TestUtilsV2.createDBEntity();
+        AtlasEntity dbEntity = dbEntityMap.values().iterator().next();
+
+        Map<String, AtlasEntity> tableEntityMap = TestUtilsV2.createTableEntity(dbEntity.getGuid());
+        AtlasEntity tableEntity = tableEntityMap.values().iterator().next();
 
-        AtlasEntity tableEntity = TestUtilsV2.createTableEntity(dbEntity.getGuid());
         final AtlasEntity colEntity = TestUtilsV2.createColumnEntity(tableEntity.getGuid());
         List<AtlasEntity> columns = new ArrayList<AtlasEntity>() {{ add(colEntity); }};
         tableEntity.setAttribute("columns", columns);
@@ -139,9 +150,9 @@ public class TestEntitiesREST {
         AtlasEntity newDBEntity = serDeserEntity(dbEntity);
         AtlasEntity newTableEntity = serDeserEntity(tableEntity);
 
-        List<AtlasEntity> newEntities = new ArrayList<AtlasEntity>();
-        newEntities.add(newDBEntity);
-        newEntities.add(newTableEntity);
+        Map<String, AtlasEntity> newEntities = new HashMap<>();
+        newEntities.put(newDBEntity.getGuid(), newDBEntity);
+        newEntities.put(newTableEntity.getGuid(), newTableEntity);
         EntityMutationResponse response2 = entitiesREST.createOrUpdate(newEntities);
 
         List<AtlasEntityHeader> newGuids = response2.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE);
@@ -211,7 +222,7 @@ public class TestEntitiesREST {
             //date
             Assert.assertEquals(tableEntity.getAttribute("created"), retrievedTableEntity.getAttribute("created"));
             //array of Ids
-            Assert.assertEquals(((List<AtlasEntity>) retrievedTableEntity.getAttribute("columns")).get(0).getGuid(), retrievedColumnEntity.getGuid());
+            Assert.assertEquals(((List<AtlasObjectId>) retrievedTableEntity.getAttribute("columns")).get(0).getGuid(), retrievedColumnEntity.getGuid());
             //array of structs
             Assert.assertEquals(((List<AtlasStruct>) retrievedTableEntity.getAttribute("partitions")), tableEntity.getAttribute("partitions"));
         }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityREST.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityREST.java b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityREST.java
index ee36fdf..2d49c47 100644
--- a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityREST.java
+++ b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityREST.java
@@ -29,6 +29,7 @@ import org.apache.atlas.model.instance.EntityMutations;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
 import org.apache.atlas.repository.graph.AtlasGraphProvider;
 import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.web.rest.EntitiesREST;
 import org.apache.atlas.web.rest.EntityREST;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
@@ -41,6 +42,7 @@ import javax.inject.Inject;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 @Guice(modules = {RepositoryMetadataModule.class})
 public class TestEntityREST {
@@ -51,6 +53,9 @@ public class TestEntityREST {
     @Inject
     private EntityREST entityREST;
 
+    @Inject
+    private EntitiesREST entitiesREST;
+
     private AtlasEntity dbEntity;
 
     private String dbGuid;
@@ -61,7 +66,8 @@ public class TestEntityREST {
     public void setUp() throws Exception {
         AtlasTypesDef typesDef = TestUtilsV2.defineHiveTypes();
         typeStore.createTypesDef(typesDef);
-        dbEntity = TestUtilsV2.createDBEntity();
+        Map<String, AtlasEntity> dbEntityMap = TestUtilsV2.createDBEntity();
+        dbEntity = dbEntityMap.values().iterator().next();
     }
 
     @AfterClass
@@ -74,9 +80,10 @@ public class TestEntityREST {
         RequestContext.clear();
     }
 
-    @Test
-    public void testCreateOrUpdateEntity() throws Exception {
-        final EntityMutationResponse response = entityREST.createOrUpdate(dbEntity);
+    public void createOrUpdateEntity() throws Exception {
+        Map<String, AtlasEntity> dbEntityMap = new HashMap<>();
+        dbEntityMap.put(dbEntity.getGuid(), dbEntity);
+        final EntityMutationResponse response = entitiesREST.createOrUpdate(dbEntityMap);
 
         Assert.assertNotNull(response);
         List<AtlasEntityHeader> entitiesMutated = response.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE);
@@ -88,18 +95,19 @@ public class TestEntityREST {
         Assert.assertEquals(entitiesMutated.size(), 1);
     }
 
-    @Test(dependsOnMethods = "testCreateOrUpdateEntity")
+    @Test
     public void testGetEntityById() throws Exception {
-
-        final AtlasEntity response = entityREST.getById(dbGuid);
+        createOrUpdateEntity();
+        final List<AtlasEntityWithAssociations> response = entityREST.getById(dbGuid);
 
         Assert.assertNotNull(response);
-        TestEntitiesREST.verifyAttributes(response.getAttributes(), dbEntity.getAttributes());
+        TestEntitiesREST.verifyAttributes(response.get(0).getAttributes(), dbEntity.getAttributes());
     }
 
-    @Test(dependsOnMethods = "testCreateOrUpdateEntity")
+    @Test
     public void  testAddAndGetClassification() throws Exception {
 
+        createOrUpdateEntity();
         List<AtlasClassification> classifications = new ArrayList<>();
         testClassification = new AtlasClassification(TestUtilsV2.CLASSIFICATION, new HashMap<String, Object>() {{ put("tag", "tagName"); }});
         classifications.add(testClassification);
@@ -122,8 +130,8 @@ public class TestEntityREST {
     @Test(dependsOnMethods = "testAddAndGetClassification")
     public void  testGetEntityWithAssociations() throws Exception {
 
-        AtlasEntityWithAssociations entity = entityREST.getWithAssociationsByGuid(dbGuid);
-        final List<AtlasClassification> retrievedClassifications = entity.getClassifications();
+        List<AtlasEntityWithAssociations> entity = entityREST.getWithAssociationsByGuid(dbGuid);
+        final List<AtlasClassification> retrievedClassifications = entity.get(0).getClassifications();
 
         Assert.assertNotNull(retrievedClassifications);
         Assert.assertEquals(new ArrayList<AtlasClassification>() {{ add(testClassification); }}, retrievedClassifications);
@@ -151,8 +159,8 @@ public class TestEntityREST {
     @Test
     public void  testUpdateGetDeleteEntityByUniqueAttribute() throws Exception {
 
-        AtlasEntity dbEntity = TestUtilsV2.createDBEntity();
-        entityREST.createOrUpdate(dbEntity);
+        Map<String, AtlasEntity> dbEntityMap = TestUtilsV2.createDBEntity();
+        entitiesREST.createOrUpdate(dbEntityMap);
 
         final String prevDBName = (String) dbEntity.getAttribute(TestUtilsV2.NAME);
         final String updatedDBName = "updatedDBName";
@@ -164,11 +172,11 @@ public class TestEntityREST {
         Assert.assertTrue(AtlasEntity.isAssigned(dbGuid));
 
         //Get By unique attribute
-        AtlasEntity entity = entityREST.getByUniqueAttribute(TestUtilsV2.DATABASE_TYPE, TestUtilsV2.NAME, updatedDBName);
-        Assert.assertNotNull(entity);
-        Assert.assertNotNull(entity.getGuid());
-        Assert.assertEquals(entity.getGuid(), dbGuid);
-        TestEntitiesREST.verifyAttributes(entity.getAttributes(), dbEntity.getAttributes());
+        List<AtlasEntityWithAssociations> entities = entityREST.getByUniqueAttribute(TestUtilsV2.DATABASE_TYPE, TestUtilsV2.NAME, updatedDBName);
+        Assert.assertNotNull(entities);
+        Assert.assertNotNull(entities.get(0).getGuid());
+        Assert.assertEquals(entities.get(0).getGuid(), dbGuid);
+        TestEntitiesREST.verifyAttributes(entities.get(0).getAttributes(), dbEntity.getAttributes());
 
         final EntityMutationResponse deleteResponse = entityREST.deleteByUniqueAttribute(TestUtilsV2.DATABASE_TYPE, TestUtilsV2.NAME, (String) dbEntity.getAttribute(TestUtilsV2.NAME));
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/test/java/org/apache/atlas/web/resources/EntityV2JerseyResourceIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/atlas/web/resources/EntityV2JerseyResourceIT.java b/webapp/src/test/java/org/apache/atlas/web/resources/EntityV2JerseyResourceIT.java
index d9bffe9..29a6d49 100755
--- a/webapp/src/test/java/org/apache/atlas/web/resources/EntityV2JerseyResourceIT.java
+++ b/webapp/src/test/java/org/apache/atlas/web/resources/EntityV2JerseyResourceIT.java
@@ -564,7 +564,7 @@ public class EntityV2JerseyResourceIT extends BaseResourceIT {
         hiveTable.setAttribute("columns", columns);
 
         LOG.debug("Updating entity= " + tableUpdated);
-        EntityMutationResponse updateResult = entitiesClientV2.updateEntity(hiveTable.getGuid(), tableUpdated);
+        EntityMutationResponse updateResult = entitiesClientV2.updateEntity(tableUpdated);
         assertNotNull(updateResult);
         assertNotNull(updateResult.getEntitiesByOperation(EntityMutations.EntityOperation.UPDATE));
         assertTrue(updateResult.getEntitiesByOperation(EntityMutations.EntityOperation.UPDATE).size() > 0);


[3/3] incubator-atlas git commit: ATLAS-1522: V2 entity API changes to accept only AtlasObjectId for child references

Posted by ma...@apache.org.
ATLAS-1522: V2 entity API changes to accept only AtlasObjectId for child references

Signed-off-by: Madhan Neethiraj <ma...@apache.org>


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

Branch: refs/heads/master
Commit: d8c2a10e080eb79ba23f646270313089b2afdfda
Parents: 02cf8c4
Author: Suma Shivaprasad <su...@gmail.com>
Authored: Fri Feb 3 04:15:41 2017 -0800
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Fri Feb 3 15:18:05 2017 -0800

----------------------------------------------------------------------
 .../org/apache/atlas/AtlasEntitiesClientV2.java |  25 +-
 .../java/org/apache/atlas/AtlasErrorCode.java   |   2 +
 .../atlas/model/instance/AtlasEntity.java       |  75 ++--
 .../instance/AtlasEntityWithAssociations.java   |   4 +
 .../atlas/model/instance/AtlasObjectId.java     |  38 ++
 .../model/instance/EntityMutationResponse.java  |  28 ++
 .../org/apache/atlas/type/AtlasEntityType.java  |  18 +-
 .../org/apache/atlas/type/AtlasStructType.java  |  17 +-
 .../test/java/org/apache/atlas/TestUtilsV2.java |  34 +-
 .../store/graph/AtlasEntityStore.java           |  52 +--
 .../graph/EntityGraphDiscoveryContext.java      | 165 +++++---
 .../graph/v1/AtlasEntityGraphDiscoveryV1.java   | 110 +++---
 .../store/graph/v1/AtlasEntityStoreV1.java      |  93 ++---
 .../store/graph/v1/DeleteHandlerV1.java         |   1 +
 .../store/graph/v1/EntityGraphMapper.java       |  20 +-
 .../store/graph/v1/EntityMutationContext.java   |  73 ++--
 .../repository/store/graph/v1/EntityStream.java |  32 ++
 .../store/graph/v1/IDBasedEntityResolver.java   |  53 +--
 .../store/graph/v1/InMemoryMapEntityStream.java |  60 +++
 .../graph/v1/UniqAttrBasedEntityResolver.java   | 150 +++++--
 .../store/graph/v1/AtlasEntityStoreV1Test.java  | 390 +++++++++++--------
 .../web/adapters/AtlasArrayFormatConverter.java |   8 +-
 .../AtlasClassificationFormatConverter.java     |   6 +-
 .../adapters/AtlasEntityFormatConverter.java    |  27 +-
 .../web/adapters/AtlasEnumFormatConverter.java  |   4 +-
 .../web/adapters/AtlasFormatConverter.java      |  54 ++-
 .../web/adapters/AtlasInstanceRestAdapters.java |  36 +-
 .../web/adapters/AtlasMapFormatConverter.java   |  12 +-
 .../web/adapters/AtlasObjectIdConverter.java    |  90 +++++
 .../adapters/AtlasPrimitiveFormatConverter.java |   4 +-
 .../adapters/AtlasStructFormatConverter.java    |  44 ++-
 .../org/apache/atlas/web/rest/EntitiesREST.java |  56 +--
 .../org/apache/atlas/web/rest/EntityREST.java   |  69 ++--
 .../atlas/web/adapters/TestEntitiesREST.java    |  33 +-
 .../atlas/web/adapters/TestEntityREST.java      |  44 ++-
 .../web/resources/EntityV2JerseyResourceIT.java |   2 +-
 36 files changed, 1189 insertions(+), 740 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java b/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java
index 8d1bfa7..2b3669d 100644
--- a/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java
+++ b/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java
@@ -32,7 +32,9 @@ import org.apache.hadoop.security.UserGroupInformation;
 import javax.ws.rs.HttpMethod;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import static org.apache.atlas.model.instance.AtlasEntity.AtlasEntities;
 
@@ -43,12 +45,11 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
 
     private static final APIInfo GET_ENTITY_BY_GUID = new APIInfo(ENTITY_API + "guid/", HttpMethod.GET, Response.Status.OK);
     private static final APIInfo GET_ENTITY_WITH_ASSOCIATION_BY_GUID = new APIInfo(ENTITY_API + "guid/%s/associations", HttpMethod.GET, Response.Status.OK);
-    private static final APIInfo CREATE_ENTITY = new APIInfo(ENTITY_API, HttpMethod.POST, Response.Status.OK);
+    private static final APIInfo CREATE_ENTITY = new APIInfo(ENTITIES_API, HttpMethod.POST, Response.Status.OK);
     private static final APIInfo UPDATE_ENTITY = CREATE_ENTITY;
     private static final APIInfo GET_ENTITY_BY_ATTRIBUTE = new APIInfo(ENTITY_API + "uniqueAttribute/type/%s/attribute/%s", HttpMethod.GET, Response.Status.OK);
     private static final APIInfo UPDATE_ENTITY_BY_ATTRIBUTE = new APIInfo(ENTITY_API + "uniqueAttribute/type/%s/attribute/%s", HttpMethod.PUT, Response.Status.OK);
     private static final APIInfo DELETE_ENTITY_BY_ATTRIBUTE = new APIInfo(ENTITY_API + "uniqueAttribute/type/%s/attribute/%s", HttpMethod.DELETE, Response.Status.OK);
-    private static final APIInfo UPDATE_ENTITY_BY_GUID = new APIInfo(ENTITY_API + "guid/", HttpMethod.PUT, Response.Status.OK);
     private static final APIInfo DELETE_ENTITY_BY_GUID = new APIInfo(ENTITY_API + "guid/", HttpMethod.DELETE, Response.Status.OK);
     private static final APIInfo DELETE_ENTITY_BY_GUIDS = new APIInfo(ENTITIES_API + "guids/", HttpMethod.DELETE, Response.Status.OK);
     private static final APIInfo GET_CLASSIFICATIONS = new APIInfo(ENTITY_API + "guid/%s/classifications", HttpMethod.GET, Response.Status.OK);
@@ -113,16 +114,12 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
         return callAPI(formatPathForPathParams(DELETE_ENTITY_BY_ATTRIBUTE, type, attribute), null, EntityMutationResponse.class, queryParams);
     }
 
-    public EntityMutationResponse createEntity(AtlasEntity atlasEntity) throws AtlasServiceException {
-        return callAPI(CREATE_ENTITY, atlasEntity, EntityMutationResponse.class);
+    public EntityMutationResponse createEntity(final AtlasEntity atlasEntity) throws AtlasServiceException {
+        return callAPI(CREATE_ENTITY, new HashMap<String, AtlasEntity>() {{ put(atlasEntity.getGuid(), atlasEntity); }}, EntityMutationResponse.class);
     }
 
-    public EntityMutationResponse updateEntity(AtlasEntity atlasEntity) throws AtlasServiceException {
-        return callAPI(UPDATE_ENTITY, atlasEntity, EntityMutationResponse.class);
-    }
-
-    public EntityMutationResponse updateEntity(String guid, AtlasEntity atlasEntity) throws AtlasServiceException {
-        return callAPI(UPDATE_ENTITY_BY_GUID, atlasEntity, EntityMutationResponse.class, guid);
+    public EntityMutationResponse updateEntity(final AtlasEntity atlasEntity) throws AtlasServiceException {
+        return callAPI(UPDATE_ENTITY, new HashMap<String, AtlasEntity>() {{ put(atlasEntity.getGuid(), atlasEntity); }}, EntityMutationResponse.class);
     }
 
     public AtlasEntity deleteEntityByGuid(String guid) throws AtlasServiceException {
@@ -159,15 +156,11 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
         return null;
     }
 
-    public List<AtlasEntity> createEntities(List<AtlasEntity> atlasEntities) throws AtlasServiceException {
+    public List<AtlasEntity> createEntities(Map<String, AtlasEntity> atlasEntities) throws AtlasServiceException {
         return (List<AtlasEntity>)callAPI(CREATE_ENTITIES, atlasEntities, List.class);
     }
 
-    public List<AtlasEntity> updateEntities(List<AtlasEntity> atlasEntities) throws AtlasServiceException {
+    public List<AtlasEntity> updateEntities(Map<String, AtlasEntity> atlasEntities) throws AtlasServiceException {
         return (List<AtlasEntity>)callAPI(UPDATE_ENTITIES, atlasEntities, List.class);
     }
-
-    public AtlasEntity.AtlasEntities searchEntities(SearchFilter searchFilter) throws AtlasServiceException {
-        return callAPI(GET_ENTITIES, AtlasEntity.AtlasEntities.class, searchFilter.getParams());
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/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 0fb16c6..49289d8 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -80,6 +80,8 @@ public enum AtlasErrorCode {
 
     INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND(400, "ATLAS40018E", "Instance {0} with unique attribute {1} does not exist"),
 
+    UNRESOLVED_REFERENCES_FOUND(400, "ATLAS40010E", "Unresolved references: byId={0}; byUniqueAttributes={1}"),
+
     UNKNOWN_ATTRIBUTE(400, "ATLAS40019E", "Attribute {0} not found for type {1}");
 
     private String errorCode;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
index 9494fe4..de57145 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
@@ -161,6 +161,41 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
         this.version = version;
     }
 
+    @JsonIgnore
+    public boolean isUnassigned() {
+        return isUnAssigned(guid);
+    }
+
+    @JsonIgnore
+    public boolean isAssigned() {
+        return isAssigned(guid);
+    }
+
+    @JsonIgnore
+    public static boolean isAssigned(String guid) {
+        try {
+            UUID.fromString(guid);
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @JsonIgnore
+    public static boolean isUnAssigned(String guid) {
+        return guid != null && guid.length() > 0 && guid.charAt(0) == '-';
+    }
+
+    private static String nextInternalId() {
+        return "-" + Long.toString(s_nextId.getAndIncrement());
+    }
+
+    @JsonIgnore
+    public AtlasObjectId getAtlasObjectId() {
+        return new AtlasObjectId(getTypeName(), getGuid());
+    }
+
     @Override
     public StringBuilder toString(StringBuilder sb) {
         if (sb == null) {
@@ -233,44 +268,4 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
             super(list, startIndex, pageSize, totalCount, sortType, sortBy);
         }
     }
-
-    @JsonIgnore
-    public boolean validate(String id) {
-        try {
-            long l = Long.parseLong(id);
-            return l < 0;
-        } catch (NumberFormatException ne) {
-            return false;
-        }
-    }
-
-    @JsonIgnore
-    public boolean isUnassigned() {
-        return isUnAssigned(guid);
-    }
-
-    @JsonIgnore
-    public boolean isAssigned() {
-        return isAssigned(guid);
-    }
-
-    @JsonIgnore
-    public static boolean isAssigned(String guid) {
-        try {
-            UUID.fromString(guid);
-        } catch (IllegalArgumentException e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    @JsonIgnore
-    public static boolean isUnAssigned(String guid) {
-        return guid != null && guid.length() > 0 && guid.charAt(0) == '-';
-    }
-
-    private String nextInternalId() {
-        return "-" + Long.toString(s_nextId.getAndIncrement());
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java
index 932a40d..abcf276 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java
@@ -73,6 +73,10 @@ public class AtlasEntityWithAssociations extends AtlasEntity implements Serializ
         setClassifications(other != null ? other.getClassifications() : null);
     }
 
+    public AtlasEntityWithAssociations(AtlasEntity other) {
+        super(other);
+    }
+
     @Override
     public StringBuilder toString(StringBuilder sb) {
         if (sb == null) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java
index 738f22f..e4abda7 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java
@@ -30,10 +30,13 @@ import javax.xml.bind.annotation.XmlSeeAlso;
 import org.apache.atlas.model.PList;
 import org.apache.atlas.model.SearchFilter.SortType;
 import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
 import org.codehaus.jackson.annotate.JsonAutoDetect;
 import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
 import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
 
+import org.codehaus.jackson.annotate.JsonIgnore;
 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
@@ -56,6 +59,12 @@ public class AtlasObjectId  implements Serializable {
     private String              guid;
     private Map<String, Object> uniqueAttributes;
 
+    @JsonIgnore
+    private boolean isAssignedGuid = false;
+
+    @JsonIgnore
+    private boolean isUnAssignedGuid = false;
+
     public AtlasObjectId() {
         this(null, null, null);
     }
@@ -120,6 +129,10 @@ public class AtlasObjectId  implements Serializable {
 
     public void setGuid(String guid) {
         this.guid = guid;
+        if ( guid != null) {
+            this.isAssignedGuid = AtlasEntity.isAssigned(guid);
+            this.isUnAssignedGuid = AtlasEntity.isUnAssigned(guid);
+        }
     }
 
     public Map<String, Object> getUniqueAttributes() {
@@ -130,6 +143,31 @@ public class AtlasObjectId  implements Serializable {
         this.uniqueAttributes = uniqueAttributes;
     }
 
+    @JsonIgnore
+    public boolean isAssignedGuid() {
+        return isAssignedGuid;
+    }
+
+    @JsonIgnore
+    public boolean isUnAssignedGuid() {
+        return isUnAssignedGuid;
+    }
+
+    @JsonIgnore
+    public boolean isValid() {
+        if (StringUtils.isEmpty(typeName)) {
+            return false;
+        } else if (StringUtils.isNotEmpty(guid)) {
+            if (!isAssignedGuid && !isUnAssignedGuid) {
+                return false;
+            }
+        } else if (MapUtils.isEmpty(uniqueAttributes)) {
+            return false;
+        }
+
+        return true;
+    }
+
     public StringBuilder toString(StringBuilder sb) {
         if (sb == null) {
             sb = new StringBuilder();

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java b/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java
index c9b6e97..874a43a 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java
@@ -89,6 +89,34 @@ public class EntityMutationResponse {
         return null;
     }
 
+    @JsonIgnore
+    public AtlasEntityHeader getFirstCreatedEntityByTypeName(String typeName) {
+        final List<AtlasEntityHeader> entitiesByOperation = getEntitiesByOperation(EntityMutations.EntityOperation.CREATE);
+        if ( entitiesByOperation != null && entitiesByOperation.size() > 0) {
+            for (AtlasEntityHeader header : entitiesByOperation) {
+                if ( header.getTypeName().equals(typeName)) {
+                    return header;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    @JsonIgnore
+    public AtlasEntityHeader getFirstUpdatedEntityByTypeName(String typeName) {
+        final List<AtlasEntityHeader> entitiesByOperation = getEntitiesByOperation(EntityMutations.EntityOperation.UPDATE);
+        if ( entitiesByOperation != null && entitiesByOperation.size() > 0) {
+            for (AtlasEntityHeader header : entitiesByOperation) {
+                if ( header.getTypeName().equals(typeName)) {
+                    return header;
+                }
+            }
+        }
+
+        return null;
+    }
+
     public void addEntity(EntityMutations.EntityOperation op, AtlasEntityHeader header) {
         if (entitiesMutated == null) {
             entitiesMutated = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
----------------------------------------------------------------------
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 fcd483c..0099307 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -193,7 +193,7 @@ public class AtlasEntityType extends AtlasStructType {
         if (obj != null) {
             if (obj instanceof AtlasObjectId) {
                 AtlasObjectId objId = (AtlasObjectId ) obj;
-                return validateAtlasObjectId(objId);
+                return isAssignableFrom(objId);
             } else {
                 for (AtlasEntityType superType : superTypes) {
                     if (!superType.isValidValue(obj)) {
@@ -240,7 +240,7 @@ public class AtlasEntityType extends AtlasStructType {
         if (obj != null) {
             if (obj instanceof AtlasObjectId) {
                 AtlasObjectId objId = (AtlasObjectId ) obj;
-                return validateAtlasObjectId(objId);
+                return isAssignableFrom(objId);
             }
 
             for (AtlasEntityType superType : superTypes) {
@@ -406,16 +406,10 @@ public class AtlasEntityType extends AtlasStructType {
         return ret == null ? Collections.<String, AtlasAttribute>emptyMap() : ret;
     }
 
-    private boolean validateAtlasObjectId(AtlasObjectId objId) {
-        if (StringUtils.isEmpty(objId.getTypeName()) || StringUtils.isEmpty(objId.getGuid())) {
-            return false;
-        } else {
-            String typeName = objId.getTypeName();
-            if (!typeName.equals(getTypeName()) && !isSuperTypeOf(typeName)) {
-                return false;
-            }
-        }
-        return AtlasEntity.isAssigned(objId.getGuid()) || AtlasEntity.isUnAssigned((objId.getGuid()));
+    boolean isAssignableFrom(AtlasObjectId objId) {
+        boolean ret = objId.isValid() && (StringUtils.equals(objId.getTypeName(), getTypeName()) || isSuperTypeOf(objId.getTypeName()));
+
+        return ret;
     }
 
     public static class ForeignKeyReference {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
----------------------------------------------------------------------
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 8bdbe93..3a815b7 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -481,6 +480,22 @@ public class AtlasStructType extends AtlasType {
             return qualifiedName;
         }
 
+        /*
+         * "isContainedAttribute" can not be computed and cached in the constructor - as structType is not fully
+         * populated at the time AtlasAttribute object is constructed.
+         */
+        public boolean isContainedAttribute() {
+            if ( structType.isForeignKeyOnDeleteActionUpdate(attributeDef.getName()) ) {
+                return true;
+            }
+
+            if ( structType instanceof AtlasEntityType) {
+                return ((AtlasEntityType) structType).isMappedFromRefAttribute(attributeDef.getName());
+            }
+
+            return false;
+        }
+
         public static String getQualifiedAttributeName(AtlasStructDef structDef, String attrName) {
             final String typeName = structDef.getName();
             return attrName.contains(".") ? attrName : String.format("%s.%s", typeName, attrName);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
index 0756937..b4aa8aa 100755
--- a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
+++ b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
@@ -284,7 +284,9 @@ public final class TestUtilsV2 {
     public static final String PERSON_TYPE = "Person";
     public static final String EMPLOYEE_TYPE = "Employee";
 
-    public static AtlasEntity createDeptEg1() {
+    public static Map<String, AtlasEntity> createDeptEg1() {
+        Map<String, AtlasEntity> deptEmpEntities = new HashMap<>();
+
         AtlasEntity hrDept = new AtlasEntity(DEPARTMENT_TYPE);
         AtlasEntity john = new AtlasEntity(EMPLOYEE_TYPE);
 
@@ -329,7 +331,8 @@ public final class TestUtilsV2 {
         julius.setAttribute("address", juliusAddr);
         julius.setAttribute("subordinates", ImmutableList.of());
 
-        AtlasObjectId janeId = new AtlasObjectId(jane.getTypeName(), jane.getGuid());
+        AtlasObjectId janeId = jane.getAtlasObjectId();
+        AtlasObjectId johnId = john.getAtlasObjectId();
 
         //TODO - Change to MANAGER_TYPE for JULIUS
         AtlasObjectId maxId = new AtlasObjectId(EMPLOYEE_TYPE, max.getGuid());
@@ -355,15 +358,20 @@ public final class TestUtilsV2 {
 
         john.setAttribute("manager", janeId);
         john.setAttribute("mentor", maxId);
-        hrDept.setAttribute("employees", ImmutableList.of(john, jane, julius, max));
+        hrDept.setAttribute("employees", ImmutableList.of(johnId, janeId, juliusId, maxId));
 
-        jane.setAttribute("subordinates", ImmutableList.of(john, max));
+        jane.setAttribute("subordinates", ImmutableList.of(johnId, maxId));
 
 //        Map<String, Integer> secClearanceLevelMap = new HashMap<>();
 //        secClearanceLevelMap.put("level", 1);
 //        jane.setAttribute("SecurityClearance", secClearanceLevelMap);
 
-        return hrDept;
+        deptEmpEntities.put(jane.getGuid(), jane);
+        deptEmpEntities.put(john.getGuid(), john);
+        deptEmpEntities.put(julius.getGuid(), julius);
+        deptEmpEntities.put(max.getGuid(), max);
+        deptEmpEntities.put(deptId.getGuid(), hrDept);
+        return deptEmpEntities;
     }
 
     public static final String DATABASE_TYPE = "hive_database";
@@ -661,15 +669,20 @@ public final class TestUtilsV2 {
         return RandomStringUtils.randomAlphanumeric(10);
     }
 
-    public static AtlasEntity createDBEntity() {
+    public static Map<String, AtlasEntity> createDBEntity() {
+        Map<String, AtlasEntity> ret = new HashMap<>();
         AtlasEntity entity = new AtlasEntity(DATABASE_TYPE);
         String dbName = RandomStringUtils.randomAlphanumeric(10);
         entity.setAttribute(NAME, dbName);
         entity.setAttribute("description", "us db");
-        return entity;
+
+        ret.put(entity.getGuid(), entity);
+        return ret;
     }
 
-    public static AtlasEntity createTableEntity(String dbId) {
+    public static Map<String, AtlasEntity> createTableEntity(String dbId) {
+        Map<String, AtlasEntity> ret = new HashMap<>();
+
         AtlasEntity entity = new AtlasEntity(TABLE_TYPE);
         String tableName = RandomStringUtils.randomAlphanumeric(10);
         entity.setAttribute(NAME, tableName);
@@ -688,10 +701,13 @@ public final class TestUtilsV2 {
         entity.setAttribute("parametersMap", new java.util.HashMap<String, String>() {{
             put("key1", "value1");
         }});
-        return entity;
+
+        ret.put(entity.getGuid(), entity);
+        return ret;
     }
 
     public static AtlasEntity createColumnEntity(String tableId) {
+
         AtlasEntity entity = new AtlasEntity(COLUMN_TYPE);
         entity.setAttribute(NAME, RandomStringUtils.randomAlphanumeric(10));
         entity.setAttribute("type", "VARCHAR(32)");

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
index c42f95f..ed0fabb 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
@@ -28,6 +28,7 @@ import org.apache.atlas.model.instance.EntityMutationResponse;
 import org.apache.atlas.type.AtlasTypeRegistry;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * Persistence/Retrieval API for AtlasEntity
@@ -37,23 +38,8 @@ public interface AtlasEntityStore {
     /**
      * Initialization
      */
-    void init(AtlasTypeRegistry typeRegistry, EntityGraphDiscovery graphDiscovery) throws AtlasBaseException;
+    void init(AtlasTypeRegistry typeRegistry) throws AtlasBaseException;
 
-    /**
-     * Create or update an entity if it already exists.
-     * @param entity
-     * @return
-     */
-    EntityMutationResponse createOrUpdate(AtlasEntity entity) throws AtlasBaseException;
-
-
-    /**
-     * Update entity identified by its guid
-     * @param guid
-     * @param entity
-     * @return
-     */
-    EntityMutationResponse updateById(String guid, AtlasEntity entity);
 
     /**
      *
@@ -70,25 +56,14 @@ public interface AtlasEntityStore {
      */
     EntityMutationResponse deleteById(String guid);
 
-
     /**
-     * Create or update a list of entities
-     * @param entities List of AtlasEntity objects that need to be created
+     * Create or update  entities
+     * @param entities Map of the entity Id(guid or transient Id) to AtlasEntity objects that need to be created
      * @return EntityMutationResponse Entity mutations operations with the correspomding set of entities on which these operations were performed
      * @throws AtlasBaseException
      */
 
-    EntityMutationResponse createOrUpdate(List<AtlasEntity> entities) throws AtlasBaseException;
-
-    /**
-     *
-     * Provides list of updated entity guids including any child entities
-     * @param guid
-     * @param entity
-     * @return
-     * @throws AtlasBaseException
-     */
-    EntityMutationResponse updateByIds(String guid, AtlasEntity entity) throws AtlasBaseException;
+    EntityMutationResponse createOrUpdate(Map<String, AtlasEntity> entities) throws AtlasBaseException;
 
     /**
      * Batch GET to retrieve entities by their ID
@@ -145,14 +120,6 @@ public interface AtlasEntityStore {
     EntityMutationResponse deleteByUniqueAttribute(String typeName, String attributeName, String attributeValue) throws AtlasBaseException;
 
     /**
-     * Compose any type of mutation op - EntityMutation.EntityOperation - CREATE_OR_UPDATE, PARTIAL_UPDATE, DELETE etc in a single transaction
-     * @param mutations
-     * @return
-     * @throws AtlasBaseException
-     */
-    EntityMutationResponse batchMutate(EntityMutations mutations) throws AtlasBaseException;
-
-    /**
      * Add classification(s)
      */
     void addClassifications(String guid, List<AtlasClassification> classification) throws AtlasBaseException;
@@ -168,13 +135,4 @@ public interface AtlasEntityStore {
      */
     void deleteClassifications(String guid, List<String> classificationNames) throws AtlasBaseException;
 
-    /**
-     *
-     * Search by AND filters like typename, pre-defined attribute(s) eg: name, qualifiedName
-     * @param searchFilter
-     * @return
-     * @throws AtlasBaseException
-     */
-    AtlasEntity.AtlasEntities searchEntities(SearchFilter searchFilter) throws AtlasBaseException;
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java
index 2d748da..cd92a11 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java
@@ -17,106 +17,145 @@
  */
 package org.apache.atlas.repository.store.graph;
 
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
 public final class EntityGraphDiscoveryContext {
+    private static final Logger LOG = LoggerFactory.getLogger(EntityGraphDiscoveryContext.class);
 
-    /**
-     *  Keeps track of all the entities that need to be created/updated including its child entities *
-     */
-    private Set<AtlasEntity> rootEntities = new LinkedHashSet<>();
+    private final AtlasTypeRegistry         typeRegistry;
+    private List<AtlasEntity>               rootEntities               = new ArrayList<>();
+    private Map<AtlasObjectId, AtlasVertex> resolvedIds                = new LinkedHashMap<>();
+    private Set<AtlasObjectId>              unresolvedIds              = new HashSet<>();
+    private List<AtlasObjectId>             unresolvedIdsByUniqAttribs = new ArrayList<>();
 
-    //Key is a transient id/guid
-    /**
-     * These references have been resolved using a unique identifier like guid or a qualified name etc in Atlas repository
-     */
-    private Map<String, AtlasVertex> repositoryResolvedReferences = new LinkedHashMap<>();
-
-    /**
-     * Unresolved entity references
-     */
-    private List<AtlasEntity> unresolvedEntityReferences = new ArrayList<>();
+    public EntityGraphDiscoveryContext(AtlasTypeRegistry typeRegistry) {
+        this.typeRegistry = typeRegistry;
+    }
 
-    /**
-     * Unresolved entity id references
-     */
-    private Set<AtlasObjectId> unresolvedIdReferences = new HashSet<>();
 
-    public void addRepositoryResolvedReference(AtlasObjectId id, AtlasVertex vertex) {
-        repositoryResolvedReferences.put(id.getGuid(), vertex);
+    public Collection<AtlasEntity> getRootEntities() {
+        return rootEntities;
     }
 
-    public void addUnResolvedEntityReference(AtlasEntity entity) {
-        this.unresolvedEntityReferences.add(entity);
+    public Map<AtlasObjectId, AtlasVertex> getResolvedIds() {
+        return resolvedIds;
     }
 
-    public void addUnResolvedIdReference(AtlasEntityType entityType, String id) {
-        this.unresolvedIdReferences.add(new AtlasObjectId(entityType.getTypeName(), id));
+    public Set<AtlasObjectId> getUnresolvedIds() {
+        return unresolvedIds;
     }
 
-    public Set<AtlasObjectId> getUnresolvedIdReferences() {
-        return unresolvedIdReferences;
+    public List<AtlasObjectId> getUnresolvedIdsByUniqAttribs() {
+        return unresolvedIdsByUniqAttribs;
     }
 
-    public boolean isResolved(String guid) {
-        return repositoryResolvedReferences.containsKey(guid);
-    }
 
-    public AtlasVertex getResolvedReference(AtlasObjectId ref) {
-        return repositoryResolvedReferences.get(ref.getGuid());
+    public void addRootEntity(AtlasEntity rootEntity) {
+        this.rootEntities.add(rootEntity);
     }
 
-    public Map<String, AtlasVertex> getRepositoryResolvedReferences() {
-        return repositoryResolvedReferences;
-    }
 
-    public AtlasVertex getResolvedReference(String id) {
-        return repositoryResolvedReferences.get(id);
+    public void addResolvedId(AtlasObjectId objId, AtlasVertex vertex) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("addResolvedId({})", objId);
+        }
+
+        resolvedIds.put(objId, vertex);
     }
 
-    public List<AtlasEntity> getUnResolvedEntityReferences() {
-        return unresolvedEntityReferences;
+    public boolean removeUnResolvedId(AtlasObjectId objId) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("removeUnResolvedId({})", objId);
+        }
+
+        return unresolvedIds.remove(objId);
     }
 
-    public void addRootEntity(AtlasEntity rootEntity) {
-        this.rootEntities.add(rootEntity);
+
+    public void addUnResolvedId(AtlasObjectId objId) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("addUnResolvedId({})", objId);
+        }
+
+        this.unresolvedIds.add(objId);
     }
 
-    public Collection<AtlasEntity> getRootEntities() {
-        return rootEntities;
+    public boolean removeUnResolvedIds(List<AtlasObjectId> objIds) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("removeUnResolvedIds({})", objIds);
+        }
+
+        return unresolvedIds.removeAll(objIds);
     }
 
-    public boolean removeUnResolvedEntityReference(final AtlasEntity entity) {
-        return unresolvedEntityReferences.remove(entity);
+
+    public void addUnresolvedIdByUniqAttribs(AtlasObjectId objId) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("addUnresolvedIdByUniqAttribs({})", objId);
+        }
+
+        this.unresolvedIdsByUniqAttribs.add(objId);
     }
 
-    public boolean removeUnResolvedEntityReferences(final List<AtlasEntity> entities) {
-        return unresolvedEntityReferences.removeAll(entities);
+    public boolean removeUnresolvedIdsByUniqAttribs(List<AtlasObjectId> objIds) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("removeUnresolvedIdsByUniqAttribs({})", objIds);
+        }
+
+        return unresolvedIdsByUniqAttribs.removeAll(objIds);
     }
 
-    public boolean removeUnResolvedIdReferences(final List<AtlasObjectId> entities) {
-        return unresolvedIdReferences.removeAll(entities);
+    public boolean hasUnresolvedReferences() {
+        return unresolvedIdsByUniqAttribs.size() > 0 || unresolvedIds.size() > 0;
     }
 
-    public boolean removeUnResolvedIdReference(final AtlasObjectId entity) {
-        return unresolvedIdReferences.remove(entity);
+    public boolean isResolvedId(AtlasObjectId id) {
+        return resolvedIds.containsKey(id);
     }
 
-    public boolean hasUnresolvedReferences() {
-        return unresolvedEntityReferences.size() > 0 || unresolvedIdReferences.size() > 0;
+    public AtlasVertex getResolvedEntityVertex(AtlasObjectId ref) throws AtlasBaseException {
+        AtlasVertex vertex = resolvedIds.get(ref);
+
+        // check also for sub-types; ref={typeName=Asset; guid=abcd} should match {typeName=hive_table; guid=abcd}
+        if (vertex == null) {
+            final AtlasEntityType entityType  = typeRegistry.getEntityTypeByName(ref.getTypeName());
+            final Set<String>     allSubTypes = entityType.getAllSubTypes();
+
+            for (String subType : allSubTypes) {
+                AtlasObjectId subTypeObjId = new AtlasObjectId(subType, ref.getGuid(), ref.getUniqueAttributes());
+
+                vertex = resolvedIds.get(subTypeObjId);
+
+                if (vertex != null) {
+                    resolvedIds.put(ref, vertex);
+                    break;
+                }
+            }
+        }
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS,
+                                         " : Could not find an entity with " + ref.toString());
+        }
+
+        return vertex;
     }
 
     @Override
@@ -130,15 +169,15 @@ public final class EntityGraphDiscoveryContext {
         } else {
             EntityGraphDiscoveryContext ctx = (EntityGraphDiscoveryContext) obj;
             return Objects.equals(rootEntities, ctx.getRootEntities()) &&
-                Objects.equals(repositoryResolvedReferences, ctx.getRepositoryResolvedReferences()) &&
-                Objects.equals(unresolvedEntityReferences, ctx.getUnResolvedEntityReferences()) &&
-                Objects.equals(unresolvedIdReferences, ctx.getUnresolvedIdReferences());
+                Objects.equals(resolvedIds, ctx.getResolvedIds()) &&
+                Objects.equals(unresolvedIdsByUniqAttribs, ctx.getUnresolvedIdsByUniqAttribs()) &&
+                Objects.equals(unresolvedIds, ctx.getUnresolvedIds());
         }
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(rootEntities, repositoryResolvedReferences, unresolvedEntityReferences, unresolvedIdReferences);
+        return Objects.hash(rootEntities, resolvedIds, unresolvedIdsByUniqAttribs, unresolvedIds);
     }
 
     public StringBuilder toString(StringBuilder sb) {
@@ -148,9 +187,9 @@ public final class EntityGraphDiscoveryContext {
 
         sb.append("EntityGraphDiscoveryCtx{");
         sb.append("rootEntities='").append(rootEntities).append('\'');
-        sb.append(", repositoryResolvedReferences=").append(repositoryResolvedReferences);
-        sb.append(", unresolvedEntityReferences='").append(unresolvedEntityReferences).append('\'');
-        sb.append(", unresolvedIdReferences='").append(unresolvedIdReferences).append('\'');
+        sb.append(", resolvedIds=").append(resolvedIds);
+        sb.append(", unresolvedIdsByUniqAttribs='").append(unresolvedIdsByUniqAttribs).append('\'');
+        sb.append(", unresolvedIds='").append(unresolvedIds).append('\'');
         sb.append('}');
 
         return sb;
@@ -163,8 +202,8 @@ public final class EntityGraphDiscoveryContext {
 
     public void cleanUp() {
         rootEntities.clear();
-        unresolvedEntityReferences.clear();
-        repositoryResolvedReferences.clear();
-        unresolvedIdReferences.clear();
+        unresolvedIdsByUniqAttribs.clear();
+        resolvedIds.clear();
+        unresolvedIds.clear();
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java
index 0e1d9e6..2b0804f 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java
@@ -41,6 +41,7 @@ import org.apache.atlas.type.AtlasMapType;
 import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.commons.lang3.StringUtils;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.inject.Inject;
@@ -49,17 +50,15 @@ import com.google.inject.Provider;
 
 public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
 
-    private AtlasTypeRegistry typeRegistry;
-
-    private Set<String> processedIds = new HashSet<>();
-
-    private EntityGraphDiscoveryContext discoveredEntities = new EntityGraphDiscoveryContext();
-
-    private final Collection<EntityResolver> entityResolvers = new LinkedHashSet<>();
+    private final AtlasTypeRegistry           typeRegistry;
+    private final EntityGraphDiscoveryContext discoveredEntities;
+    private final Set<String>                 processedIds    = new HashSet<>();
+    private final Collection<EntityResolver>  entityResolvers = new LinkedHashSet<>();
 
     @Inject
-    public AtlasEntityGraphDiscoveryV1(AtlasTypeRegistry typeRegistry, final Collection<Provider<EntityResolver>> entityResolverProviders) {
-        this.typeRegistry = typeRegistry;
+    public AtlasEntityGraphDiscoveryV1(AtlasTypeRegistry typeRegistry, Collection<Provider<EntityResolver>> entityResolverProviders) {
+        this.typeRegistry       = typeRegistry;
+        this.discoveredEntities = new EntityGraphDiscoveryContext(typeRegistry);
 
         for (Provider<EntityResolver> entityResolverProvider : entityResolverProviders) {
              entityResolvers.add(entityResolverProvider.get());
@@ -67,8 +66,9 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
     }
 
     @VisibleForTesting
-    public AtlasEntityGraphDiscoveryV1(AtlasTypeRegistry typeRegistry, final List<EntityResolver> entityResolvers) {
-        this.typeRegistry = typeRegistry;
+    public AtlasEntityGraphDiscoveryV1(AtlasTypeRegistry typeRegistry, List<EntityResolver> entityResolvers) {
+        this.typeRegistry       = typeRegistry;
+        this.discoveredEntities = new EntityGraphDiscoveryContext(typeRegistry);
 
         for (EntityResolver entityResolver : entityResolvers) {
             this.entityResolvers.add(entityResolver);
@@ -96,22 +96,14 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
     public void cleanUp() throws AtlasBaseException {
         processedIds.clear();
         discoveredEntities.cleanUp();
-        final Collection<EntityResolver> entityResolvers = this.entityResolvers;
+
         for (EntityResolver resolver : entityResolvers) {
             resolver.cleanUp();
         }
     }
 
 
-    protected void resolveReferences() throws AtlasBaseException {
-        for (EntityResolver resolver : entityResolvers ) {
-            resolver.init(discoveredEntities);
-            resolver.resolveEntityReferences();
-        }
-    }
-
-
-    protected void discover(final List<AtlasEntity> entities) throws AtlasBaseException {
+    protected void discover(List<AtlasEntity> entities) throws AtlasBaseException {
         for (AtlasEntity entity : entities) {
             AtlasEntityType type = typeRegistry.getEntityTypeByName(entity.getTypeName());
 
@@ -120,27 +112,41 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
             }
 
             discoveredEntities.addRootEntity(entity);
+
             walkEntityGraph(type, entity);
         }
     }
 
-    private void visitReference(AtlasEntityType type, Object entity, boolean isManagedEntity) throws AtlasBaseException {
+    protected void resolveReferences() throws AtlasBaseException {
+        for (EntityResolver resolver : entityResolvers) {
+            resolver.init(discoveredEntities);
+
+            resolver.resolveEntityReferences();
+        }
+
+        if (discoveredEntities.hasUnresolvedReferences()) {
+            throw new AtlasBaseException(AtlasErrorCode.UNRESOLVED_REFERENCES_FOUND,
+                                                         discoveredEntities.getUnresolvedIds().toString(),
+                                                         discoveredEntities.getUnresolvedIdsByUniqAttribs().toString());
+        }
+    }
+
+    private void visitReference(AtlasEntityType type, Object entity) throws AtlasBaseException {
         if (entity != null) {
             if (entity instanceof AtlasObjectId) {
-                final String guid = ((AtlasObjectId) entity).getGuid();
-                discoveredEntities.addUnResolvedIdReference(type, guid);
-            } else if (entity instanceof AtlasEntity) {
-                AtlasEntity entityObj = (AtlasEntity) entity;
-                if (isManagedEntity) {
-                    if (!processedIds.contains(entityObj.getGuid())) {
-                        processedIds.add(entityObj.getGuid());
-
-                        discoveredEntities.addRootEntity(entityObj);
-                        visitStruct(type, entityObj);
-                    }
+                AtlasObjectId objId = (AtlasObjectId)entity;
+
+                if (!objId.isValid()) {
+                    throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, "Invalid object id " + objId);
+                }
+
+                if (!StringUtils.isEmpty(objId.getGuid()) && (objId.isAssignedGuid() || objId.isUnAssignedGuid())) {
+                    discoveredEntities.addUnResolvedId(objId);
                 } else {
-                    discoveredEntities.addUnResolvedEntityReference(entityObj);
+                    discoveredEntities.addUnresolvedIdByUniqAttribs(objId);
                 }
+            } else if (entity instanceof AtlasEntity) {
+                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, "Use AtlasObjectId to refer to another instance instead of AtlasEntity " + type.getTypeName());
             } else {
                 throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, "Invalid object type " + entity.getClass());
             }
@@ -154,26 +160,18 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
             }
             if (attrType.getTypeCategory() == TypeCategory.ARRAY) {
                 AtlasArrayType arrayType = (AtlasArrayType) attrType;
-                AtlasType elemType = arrayType.getElementType();
+                AtlasType      elemType  = arrayType.getElementType();
+
                 visitCollectionReferences(parentType, attrType, attrDef, elemType, val);
             } else if (attrType.getTypeCategory() == TypeCategory.MAP) {
-                AtlasType keyType = ((AtlasMapType) attrType).getKeyType();
+                AtlasType keyType   = ((AtlasMapType) attrType).getKeyType();
                 AtlasType valueType = ((AtlasMapType) attrType).getValueType();
+
                 visitMapReferences(parentType, attrType, attrDef, keyType, valueType, val);
             } else if (attrType.getTypeCategory() == TypeCategory.STRUCT) {
-                visitStruct(attrType, val);
+                visitStruct((AtlasStructType)attrType, val);
             } else if (attrType.getTypeCategory() == TypeCategory.ENTITY) {
-                if ( val instanceof AtlasObjectId) {
-                    visitReference((AtlasEntityType) attrType,  val, false);
-                } else if ( val instanceof AtlasEntity ) {
-                    //TODO - Change this to foreign key checks after changes in the model
-                   if ((parentType instanceof AtlasEntityType) &&
-                       ((AtlasEntityType)parentType).isMappedFromRefAttribute(attrDef.getName())) {
-                       visitReference((AtlasEntityType) attrType,  val, true);
-                   } else {
-                       visitReference((AtlasEntityType) attrType,  val, false);
-                   }
-                }
+                visitReference((AtlasEntityType) attrType,  val);
             }
         }
     }
@@ -184,7 +182,6 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
         }
 
         if (val != null) {
-
             if (Map.class.isAssignableFrom(val.getClass())) {
                 Iterator<Map.Entry> it = ((Map) val).entrySet().iterator();
                 while (it.hasNext()) {
@@ -197,7 +194,6 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
     }
 
     void visitCollectionReferences(final AtlasStructType parentType, final AtlasType attrType, final AtlasAttributeDef attrDef, AtlasType elemType, Object val) throws AtlasBaseException {
-
         if (isPrimitive(elemType.getTypeCategory())) {
             return;
         }
@@ -220,24 +216,22 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
         }
     }
 
-    void visitStruct(AtlasType type, Object val) throws AtlasBaseException {
-
-        if (val == null || !(val instanceof AtlasStruct)) {
+    void visitStruct(AtlasStructType structType, Object val) throws AtlasBaseException {
+        if (structType == null) {
             return;
         }
 
-        AtlasStructType structType = (AtlasStructType) type;
-
         for (AtlasStructType.AtlasAttribute attribute : structType.getAllAttributes().values()) {
             AtlasType attrType = attribute.getAttributeType();
-            Object attrVal = ((AtlasStruct) val).getAttribute(attribute.getName());
+            Object    attrVal  = ((AtlasStruct) val).getAttribute(attribute.getName());
+
             visitAttribute(structType, attrType, attribute.getAttributeDef(), attrVal);
         }
     }
 
 
-    void walkEntityGraph(AtlasType type, AtlasEntity entity) throws AtlasBaseException {
-        visitStruct(type, entity);
+    void walkEntityGraph(AtlasEntityType entityType, AtlasEntity entity) throws AtlasBaseException {
+        visitStruct(entityType, entity);
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
index 4c79cef..9e08282 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
@@ -25,31 +25,29 @@ import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.GraphTransaction;
 import org.apache.atlas.RequestContextV1;
 import org.apache.atlas.exception.AtlasBaseException;
-import org.apache.atlas.model.SearchFilter;
 import org.apache.atlas.model.TypeCategory;
 import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntityWithAssociations;
 import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.model.instance.EntityMutationResponse;
-import org.apache.atlas.model.instance.EntityMutations;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.AtlasEntityStore;
 import org.apache.atlas.repository.store.graph.EntityGraphDiscovery;
 import org.apache.atlas.repository.store.graph.EntityGraphDiscoveryContext;
+import org.apache.atlas.repository.store.graph.EntityResolver;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.inject.Inject;
+import java.util.Map;
 
+import com.google.inject.Inject;
 
 
 public class AtlasEntityStoreV1 implements AtlasEntityStore {
 
-    protected EntityGraphDiscovery graphDiscoverer;
     protected AtlasTypeRegistry typeRegistry;
 
     private EntityGraphMapper graphMapper;
@@ -62,22 +60,11 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
     }
 
     @Inject
-    public void init(AtlasTypeRegistry typeRegistry, EntityGraphDiscovery graphDiscoverer) throws AtlasBaseException {
-        this.graphDiscoverer = graphDiscoverer;
+    public void init(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
         this.typeRegistry = typeRegistry;
     }
 
     @Override
-    public EntityMutationResponse createOrUpdate(final AtlasEntity entity) throws AtlasBaseException {
-        return createOrUpdate(new ArrayList<AtlasEntity>() {{ add(entity); }});
-    }
-
-    @Override
-    public EntityMutationResponse updateById(final String guid, final AtlasEntity entity) {
-        return null;
-    }
-
-    @Override
     public AtlasEntity getById(final String guid) {
         return null;
     }
@@ -89,7 +76,7 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
 
     @Override
     @GraphTransaction
-    public EntityMutationResponse createOrUpdate(final List<AtlasEntity> entities) throws AtlasBaseException {
+    public EntityMutationResponse createOrUpdate(final Map<String, AtlasEntity> entities) throws AtlasBaseException {
 
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> AtlasEntityStoreV1.createOrUpdate({}, {})", entities);
@@ -109,11 +96,6 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
     }
 
     @Override
-    public EntityMutationResponse updateByIds(final String guid, final AtlasEntity entity) throws AtlasBaseException {
-        return null;
-    }
-
-    @Override
     public AtlasEntity.AtlasEntities getByIds(final List<String> guid) throws AtlasBaseException {
         return null;
     }
@@ -144,12 +126,6 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
     }
 
     @Override
-    public EntityMutationResponse batchMutate(final EntityMutations mutations) throws AtlasBaseException {
-        return null;
-    }
-
-
-    @Override
     public void addClassifications(final String guid, final List<AtlasClassification> classification) throws AtlasBaseException {
 
     }
@@ -164,42 +140,49 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
 
     }
 
-    @Override
-    public AtlasEntity.AtlasEntities searchEntities(final SearchFilter searchFilter) throws AtlasBaseException {
-        // TODO: Add checks here to ensure that typename and supertype are mandatory in the request
-        return null;
-    }
-
     private EntityMutationContext preCreateOrUpdate(final List<AtlasEntity> atlasEntities) throws AtlasBaseException {
+        List<EntityResolver> entityResolvers = new ArrayList<>();
+
+        entityResolvers.add(new IDBasedEntityResolver());
+        entityResolvers.add(new UniqAttrBasedEntityResolver(typeRegistry));
 
+        EntityGraphDiscovery        graphDiscoverer    = new AtlasEntityGraphDiscoveryV1(typeRegistry, entityResolvers);
         EntityGraphDiscoveryContext discoveredEntities = graphDiscoverer.discoverEntities(atlasEntities);
-        EntityMutationContext context = new EntityMutationContext(discoveredEntities);
-        for (AtlasEntity entity : discoveredEntities.getRootEntities()) {
+        EntityMutationContext       context            = new EntityMutationContext(discoveredEntities);
 
-            AtlasVertex vertex = null;
+        for (AtlasEntity entity : discoveredEntities.getRootEntities()) {
             if (LOG.isDebugEnabled()) {
-                LOG.debug("<== AtlasEntityStoreV1.preCreateOrUpdate({}): {}", entity);
+                LOG.debug("==> AtlasEntityStoreV1.preCreateOrUpdate({}): {}", entity);
             }
 
             AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName());
 
-            if ( entityType == null) {
+            if (entityType == null) {
                 throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), entity.getTypeName());
             }
 
-            if ( discoveredEntities.isResolved(entity.getGuid()) ) {
-                vertex = discoveredEntities.getResolvedReference(entity.getGuid());
+            final AtlasVertex vertex;
+            AtlasObjectId     objId = entity.getAtlasObjectId();
+
+            if (discoveredEntities.isResolvedId(objId) ) {
+                vertex = discoveredEntities.getResolvedEntityVertex(objId);
+
                 context.addUpdated(entity, entityType, vertex);
 
                 String guid = AtlasGraphUtilsV1.getIdFromVertex(vertex);
+
                 RequestContextV1.get().recordEntityUpdate(new AtlasObjectId(entityType.getTypeName(), guid));
             } else {
                 //Create vertices which do not exist in the repository
                 vertex = graphMapper.createVertexTemplate(entity, entityType);
+
                 context.addCreated(entity, entityType, vertex);
-                discoveredEntities.addRepositoryResolvedReference(new AtlasObjectId(entityType.getTypeName(), entity.getGuid()), vertex);
+
+                discoveredEntities.addResolvedId(objId, vertex);
+                discoveredEntities.removeUnResolvedId(objId);
 
                 String guid = AtlasGraphUtilsV1.getIdFromVertex(vertex);
+
                 RequestContextV1.get().recordEntityCreate(new AtlasObjectId(entityType.getTypeName(), guid));
             }
 
@@ -211,12 +194,21 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
         return context;
     }
 
-    private List<AtlasEntity> validateAndNormalize(final List<AtlasEntity> entities) throws AtlasBaseException {
-
+    private List<AtlasEntity> validateAndNormalize(final Map<String, AtlasEntity> entities) throws AtlasBaseException {
         List<AtlasEntity> normalizedEntities = new ArrayList<>();
-        List<String> messages = new ArrayList<>();
+        List<String>      messages           = new ArrayList<>();
+
+        for (String entityId : entities.keySet()) {
+            if ( !AtlasEntity.isAssigned(entityId) && !AtlasEntity.isUnAssigned(entityId)) {
+                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, ": Guid in map key is invalid " + entityId);
+            }
+
+            AtlasEntity entity = entities.get(entityId);
+
+            if ( entity == null) {
+                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, ": Entity is null for guid " + entityId);
+            }
 
-        for (AtlasEntity entity : entities) {
             AtlasEntityType type = typeRegistry.getEntityTypeByName(entity.getTypeName());
             if (type == null) {
                 throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), entity.getTypeName());
@@ -227,11 +219,9 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
             if ( !messages.isEmpty()) {
                 throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, messages);
             }
+
             AtlasEntity normalizedEntity = (AtlasEntity) type.getNormalizedValue(entity);
-            if ( normalizedEntity == null) {
-                //TODO - Fix this. Should not come here. Should ideally fail above
-                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, "Failed to validate entity");
-            }
+
             normalizedEntities.add(normalizedEntity);
         }
 
@@ -239,6 +229,5 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
     }
 
     public void cleanUp() throws AtlasBaseException {
-        this.graphDiscoverer.cleanUp();
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
index a989f76..f507ae0 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
@@ -25,6 +25,7 @@ import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.TypeCategory;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.graph.AtlasEdgeLabel;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
index e534d4f..a0096c1 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
@@ -88,8 +88,8 @@ public class EntityGraphMapper implements InstanceGraphMapper<AtlasEdge> {
     public AtlasEdge toGraph(GraphMutationContext ctx) throws AtlasBaseException {
         AtlasEdge result = null;
 
-        String guid = getId(ctx.getValue());
-        AtlasVertex entityVertex = context.getDiscoveryContext().getResolvedReference(guid);
+        AtlasObjectId guid = getId(ctx.getValue());
+        AtlasVertex entityVertex = context.getDiscoveryContext().getResolvedEntityVertex(guid);
         if ( ctx.getCurrentEdge().isPresent() ) {
             result = updateEdge(ctx.getAttributeDef(), ctx.getValue(), ctx.getCurrentEdge().get(), entityVertex);
         } else if (ctx.getValue() != null) {
@@ -166,12 +166,18 @@ public class EntityGraphMapper implements InstanceGraphMapper<AtlasEdge> {
     }
 
 
-    public String getId(Object value) throws AtlasBaseException {
-        if ( value != null) {
+    public AtlasObjectId getId(Object value) throws AtlasBaseException {
+        if (value != null) {
             if ( value instanceof  AtlasObjectId) {
-                return ((AtlasObjectId) value).getGuid();
+                return ((AtlasObjectId) value);
             } else if (value instanceof AtlasEntity) {
-                return ((AtlasEntity) value).getGuid();
+                return ((AtlasEntity) value).getAtlasObjectId();
+            } else if (value instanceof Map) {
+                AtlasObjectId ret = new AtlasObjectId((Map)value);
+
+                if (ret.isValid()) {
+                    return ret;
+                }
             }
 
             throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, (String) value);
@@ -211,7 +217,7 @@ public class EntityGraphMapper implements InstanceGraphMapper<AtlasEdge> {
     }
 
     public AtlasEntityType getInstanceType(Object val) throws AtlasBaseException {
-        String guid = getId(val);
+        AtlasObjectId guid = getId(val);
 
         if ( guid != null) {
             return (AtlasEntityType) getContext().getType(guid);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java
index f6e5055..310b455 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java
@@ -19,40 +19,41 @@ package org.apache.atlas.repository.store.graph.v1;
 
 import org.apache.atlas.model.instance.AtlasEntity;
 
+import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.EntityGraphDiscoveryContext;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasType;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 public class EntityMutationContext {
-
-    private List<AtlasEntity> entitiesCreated  = new ArrayList<>();
-    private List<AtlasEntity> entitiesUpdated  = new ArrayList<>();
-
-    private EntityGraphDiscoveryContext context;
-    private Map<String, AtlasEntityType> entityVsType = new HashMap<>();
-    private Map<String, AtlasVertex> entityVsVertex = new HashMap<>();
+    private final EntityGraphDiscoveryContext         context;
+    private final List<AtlasEntity>                   entitiesCreated = new ArrayList<>();
+    private final List<AtlasEntity>                   entitiesUpdated = new ArrayList<>();
+    private final Map<AtlasObjectId, AtlasEntityType> entityVsType    = new HashMap<>();
+    private final Map<AtlasObjectId, AtlasVertex>     entityVsVertex  = new HashMap<>();
 
     public EntityMutationContext(final EntityGraphDiscoveryContext context) {
         this.context = context;
     }
 
     public void addCreated(AtlasEntity entity, AtlasEntityType type, AtlasVertex atlasVertex) {
+        AtlasObjectId objId = entity.getAtlasObjectId();
         entitiesCreated.add(entity);
-        entityVsVertex.put(entity.getGuid(), atlasVertex);
-        entityVsType.put(entity.getGuid(), type);
+        entityVsType.put(objId, type);
+        entityVsVertex.put(objId, atlasVertex);
     }
 
     public void addUpdated(AtlasEntity entity, AtlasEntityType type, AtlasVertex atlasVertex) {
+        AtlasObjectId objId = entity.getAtlasObjectId();
         entitiesUpdated.add(entity);
-        entityVsVertex.put(entity.getGuid(), atlasVertex);
-        entityVsType.put(entity.getGuid(), type);
+        entityVsType.put(objId, type);
+        entityVsVertex.put(objId, atlasVertex);
+    }
+
+    public EntityGraphDiscoveryContext getDiscoveryContext() {
+        return this.context;
     }
 
     public Collection<AtlasEntity> getCreatedEntities() {
@@ -64,26 +65,21 @@ public class EntityMutationContext {
     }
 
     public AtlasEntityType getType(AtlasEntity entity) {
-        return entityVsType.get(entity.getGuid());
+        return entityVsType.get(entity.getAtlasObjectId());
     }
 
-    public AtlasType getType(String entityId) {
+    public AtlasType getType(AtlasObjectId entityId) {
         return entityVsType.get(entityId);
     }
 
     public AtlasVertex getVertex(AtlasEntity entity) {
-        return entityVsVertex.get(entity.getGuid());
+        return entityVsVertex.get(entity.getAtlasObjectId());
     }
 
-    public AtlasVertex getVertex(String entityId) {
+    public AtlasVertex getVertex(AtlasObjectId entityId) {
         return entityVsVertex.get(entityId);
     }
 
-    public EntityGraphDiscoveryContext getDiscoveryContext() {
-        return this.context;
-    }
-
-    //TODO - equals/hashCode/toString
 
     @Override
     public boolean equals(final Object o) {
@@ -92,32 +88,29 @@ public class EntityMutationContext {
 
         final EntityMutationContext that = (EntityMutationContext) o;
 
-        if (entitiesCreated != null ? !entitiesCreated.equals(that.entitiesCreated) : that.entitiesCreated != null)
-            return false;
-        if (entitiesUpdated != null ? !entitiesUpdated.equals(that.entitiesUpdated) : that.entitiesUpdated != null)
-            return false;
-        if (context != null ? !context.equals(that.context) : that.context != null) return false;
-        if (entityVsType != null ? !entityVsType.equals(that.entityVsType) : that.entityVsType != null) return false;
-        return !(entityVsVertex != null ? !entityVsVertex.equals(that.entityVsVertex) : that.entityVsVertex != null);
-
+        return Objects.equals(context, that.context) &&
+               Objects.equals(entitiesCreated, that.entitiesCreated) &&
+               Objects.equals(entitiesUpdated, that.entitiesUpdated) &&
+               Objects.equals(entityVsType, that.entityVsType) &&
+               Objects.equals(entityVsVertex, that.entityVsVertex);
     }
 
     @Override
     public int hashCode() {
-        int result = entitiesCreated != null ? entitiesCreated.hashCode() : 0;
-        result = 31 * result + (entitiesUpdated != null ? entitiesUpdated.hashCode() : 0);
-        result = 31 * result + (context != null ? context.hashCode() : 0);
-        result = 31 * result + (entityVsType != null ? entityVsType.hashCode() : 0);
-        result = 31 * result + (entityVsVertex != null ? entityVsVertex.hashCode() : 0);
+        int result = (context != null ? context.hashCode() : 0);
+        result = 31 * result + entitiesCreated.hashCode();
+        result = 31 * result + entitiesUpdated.hashCode();
+        result = 31 * result + entityVsType.hashCode();
+        result = 31 * result + entityVsVertex.hashCode();
         return result;
     }
 
     @Override
     public String toString() {
         return "EntityMutationContext{" +
-            "entitiesCreated=" + entitiesCreated +
+            "context=" + context +
+            ", entitiesCreated=" + entitiesCreated +
             ", entitiesUpdated=" + entitiesUpdated +
-            ", context=" + context +
             ", entityVsType=" + entityVsType +
             ", entityVsVertex=" + entityVsVertex +
             '}';

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityStream.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityStream.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityStream.java
new file mode 100644
index 0000000..1d939fe
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityStream.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+
+public interface EntityStream {
+
+    boolean hasNext();
+
+    AtlasEntity next();
+
+    void reset();
+
+    AtlasEntity getById(AtlasObjectId id);
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java
index d02b5a1..2ffd10e 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java
@@ -37,67 +37,70 @@ import java.util.Map;
 
 public class IDBasedEntityResolver implements EntityResolver {
 
-    private Map<String, AtlasEntity> idToEntityMap = new HashMap<>();
-
-    private final GraphHelper graphHelper = GraphHelper.getInstance();
-
-    private EntityGraphDiscoveryContext context;
+    private final GraphHelper              graphHelper   = GraphHelper.getInstance();
+    private final Map<String, AtlasEntity> idToEntityMap = new HashMap<>();
+    private EntityGraphDiscoveryContext    context;
 
     @Override
     public void init(EntityGraphDiscoveryContext context) throws AtlasBaseException {
         this.context = context;
+
         for (AtlasEntity entity : context.getRootEntities()) {
             idToEntityMap.put(entity.getGuid(), entity);
         }
     }
 
     public EntityGraphDiscoveryContext resolveEntityReferences() throws AtlasBaseException {
-
-        if ( context == null) {
+        if (context == null) {
             throw new AtlasBaseException(AtlasErrorCode.INTERNAL_ERROR, "Entity resolver not initialized");
         }
 
         List<AtlasObjectId> resolvedReferences = new ArrayList<>();
 
-        for (AtlasObjectId typeIdPair : context.getUnresolvedIdReferences()) {
-            if ( AtlasEntity.isAssigned(typeIdPair.getGuid())) {
+        for (AtlasObjectId objId : context.getUnresolvedIds()) {
+            if (objId.isAssignedGuid()) {
                 //validate in graph repo that given guid, typename exists
-                Optional<AtlasVertex> vertex = resolveGuid(typeIdPair);
+                Optional<AtlasVertex> vertex = resolveGuid(objId);
 
-                if ( vertex.isPresent() ) {
-                    context.addRepositoryResolvedReference(typeIdPair, vertex.get());
-                    resolvedReferences.add(typeIdPair);
+                if (vertex.isPresent()) {
+                    context.addResolvedId(objId, vertex.get());
+                    resolvedReferences.add(objId);
                 }
             } else {
                 //check if root references have this temporary id
-               if (!idToEntityMap.containsKey(typeIdPair.getGuid()) ) {
-                   throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, "Could not find an entity with the specified id " + typeIdPair + " in the request");
+               if (!idToEntityMap.containsKey(objId.getGuid()) ) {
+                   throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, objId.toString());
                }
+                resolvedReferences.add(objId);
             }
+
         }
 
-        context.removeUnResolvedIdReferences(resolvedReferences);
+        context.removeUnResolvedIds(resolvedReferences);
 
         //Resolve root references
         for (AtlasEntity entity : context.getRootEntities()) {
-            if ( !context.isResolved(entity.getGuid()) && AtlasEntity.isAssigned(entity.getGuid())) {
-                AtlasObjectId typeIdPair = new AtlasObjectId(entity.getTypeName(), entity.getGuid());
-                Optional<AtlasVertex> vertex = resolveGuid(typeIdPair);
+            AtlasObjectId objId = entity.getAtlasObjectId();
+
+            if (!context.isResolvedId(objId) && AtlasEntity.isAssigned(entity.getGuid())) {
+                Optional<AtlasVertex> vertex = resolveGuid(objId);
+
                 if (vertex.isPresent()) {
-                    context.addRepositoryResolvedReference(typeIdPair, vertex.get());
-                    context.removeUnResolvedIdReference(typeIdPair);
+                    context.addResolvedId(objId, vertex.get());
+                    context.removeUnResolvedId(objId);
                 }
             }
         }
+
         return context;
     }
 
-    private Optional<AtlasVertex> resolveGuid(AtlasObjectId typeIdPair) throws AtlasBaseException {
+    private Optional<AtlasVertex> resolveGuid(AtlasObjectId objId) throws AtlasBaseException {
         //validate in graph repo that given guid, typename exists
         AtlasVertex vertex = null;
         try {
-            vertex = graphHelper.findVertex(Constants.GUID_PROPERTY_KEY, typeIdPair.getGuid(),
-                Constants.TYPE_NAME_PROPERTY_KEY, typeIdPair.getTypeName(),
+            vertex = graphHelper.findVertex(Constants.GUID_PROPERTY_KEY, objId.getGuid(),
+                Constants.TYPE_NAME_PROPERTY_KEY, objId.getTypeName(),
                 Constants.STATE_PROPERTY_KEY, Id.EntityState.ACTIVE.name());
         } catch (EntityNotFoundException e) {
             //Ignore
@@ -105,7 +108,7 @@ public class IDBasedEntityResolver implements EntityResolver {
         if ( vertex != null ) {
             return Optional.of(vertex);
         } else {
-            throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, typeIdPair.getGuid());
+            throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, objId.getGuid());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/InMemoryMapEntityStream.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/InMemoryMapEntityStream.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/InMemoryMapEntityStream.java
new file mode 100644
index 0000000..0d0b949
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/InMemoryMapEntityStream.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class InMemoryMapEntityStream implements EntityStream {
+
+    private final Map<AtlasObjectId, AtlasEntity>                 entities = new HashMap<>();
+    private       Iterator<Map.Entry<AtlasObjectId, AtlasEntity>> iterator;
+
+    public InMemoryMapEntityStream(Map<String, AtlasEntity> entityMap) {
+        for (AtlasEntity entity : entityMap.values()) {
+            entities.put(entity.getAtlasObjectId(), entity);
+        }
+
+        this.iterator = entities.entrySet().iterator();
+    }
+
+    @Override
+    public boolean hasNext() {
+        return iterator.hasNext();
+    }
+
+    @Override
+    public AtlasEntity next() {
+        return iterator.hasNext() ? iterator.next().getValue() : null;
+    }
+
+    @Override
+    public void reset() {
+        iterator = entities.entrySet().iterator();
+    }
+
+    @Override
+    public AtlasEntity getById(final AtlasObjectId id) {
+        return entities.get(id);
+    }
+}


[2/3] incubator-atlas git commit: ATLAS-1522: V2 entity API changes to accept only AtlasObjectId for child references

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/UniqAttrBasedEntityResolver.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/UniqAttrBasedEntityResolver.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/UniqAttrBasedEntityResolver.java
index 76308a0..f21896d 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/UniqAttrBasedEntityResolver.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/UniqAttrBasedEntityResolver.java
@@ -23,7 +23,6 @@ import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.TypeCategory;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
-import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.graph.GraphHelper;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
@@ -33,21 +32,20 @@ import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.typesystem.exception.EntityNotFoundException;
+import org.apache.commons.collections.MapUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.inject.Inject;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 public class UniqAttrBasedEntityResolver implements EntityResolver {
-
     private static final Logger LOG = LoggerFactory.getLogger(UniqAttrBasedEntityResolver.class);
 
-    private final AtlasTypeRegistry typeRegistry;
-
-    private final GraphHelper graphHelper = GraphHelper.getInstance();
-
+    private final GraphHelper           graphHelper = GraphHelper.getInstance();
+    private final AtlasTypeRegistry     typeRegistry;
     private EntityGraphDiscoveryContext context;
 
     @Inject
@@ -56,41 +54,41 @@ public class UniqAttrBasedEntityResolver implements EntityResolver {
     }
 
     @Override
-    public void init(EntityGraphDiscoveryContext entities) throws AtlasBaseException {
-        this.context = entities;
+    public void init(EntityGraphDiscoveryContext context) throws AtlasBaseException {
+        this.context = context;
     }
 
     @Override
     public EntityGraphDiscoveryContext resolveEntityReferences() throws AtlasBaseException {
-
-        if ( context == null) {
+        if (context == null) {
             throw new AtlasBaseException(AtlasErrorCode.INTERNAL_ERROR, "Unique attribute based entity resolver not initialized");
         }
 
         //Resolve attribute references
-        List<AtlasEntity> resolvedReferences = new ArrayList<>();
+        List<AtlasObjectId> resolvedReferences = new ArrayList<>();
 
-        for (AtlasEntity entity : context.getUnResolvedEntityReferences()) {
+        for (AtlasObjectId entityId : context.getUnresolvedIdsByUniqAttribs()) {
             //query in graph repo that given unique attribute - check for deleted also?
-            Optional<AtlasVertex> vertex = resolveByUniqueAttribute(entity);
+            Optional<AtlasVertex> vertex = resolveByUniqueAttribute(entityId);
+
             if (vertex.isPresent()) {
-                context.addRepositoryResolvedReference(new AtlasObjectId(entity.getTypeName(), entity.getGuid()), vertex.get());
-                resolvedReferences.add(entity);
+                context.addResolvedId(entityId, vertex.get());
+                resolvedReferences.add(entityId);
             }
         }
 
-        context.removeUnResolvedEntityReferences(resolvedReferences);
-
-        if (context.getUnResolvedEntityReferences().size() > 0) {
-            throw new AtlasBaseException(AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND, context.getUnResolvedEntityReferences().toString());
-        }
+        context.removeUnresolvedIdsByUniqAttribs(resolvedReferences);
 
         //Resolve root references
         for (AtlasEntity entity : context.getRootEntities()) {
-            if ( !context.isResolved(entity.getGuid()) ) {
+            AtlasObjectId entityId = entity.getAtlasObjectId();
+
+            if (!context.isResolvedId(entityId) ) {
                 Optional<AtlasVertex> vertex = resolveByUniqueAttribute(entity);
+
                 if (vertex.isPresent()) {
-                    context.addRepositoryResolvedReference(new AtlasObjectId(entity.getTypeName(), entity.getGuid()), vertex.get());
+                    context.addResolvedId(entityId, vertex.get());
+                    context.removeUnResolvedId(entityId);
                 }
             }
         }
@@ -108,23 +106,57 @@ public class UniqAttrBasedEntityResolver implements EntityResolver {
         for (AtlasStructType.AtlasAttribute attr : entityType.getAllAttributes().values()) {
             if (attr.getAttributeDef().getIsUnique()) {
                 Object attrVal = entity.getAttribute(attr.getName());
-                if (attrVal != null) {
-                    String qualifiedAttrName = attr.getQualifiedAttributeName();
-                    AtlasVertex vertex = null;
-                    try {
-                        vertex = graphHelper.findVertex(qualifiedAttrName, attrVal,
-                            Constants.ENTITY_TYPE_PROPERTY_KEY, entityType.getTypeName(),
-                            Constants.STATE_PROPERTY_KEY, AtlasEntity.Status.ACTIVE
-                                .name());
-
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("Found vertex by unique attribute : " + qualifiedAttrName + "=" + attrVal);
-                        }
-                        if (vertex != null) {
-                            return Optional.of(vertex);
-                        }
-                    } catch (EntityNotFoundException e) {
-                        //Ignore if not found
+
+                if (attrVal == null) {
+                    continue;
+                }
+
+                Optional<AtlasVertex> vertex = findByTypeAndQualifiedName(entityType.getTypeName(), attr.getQualifiedAttributeName(), attrVal);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found vertex by unique attribute : " + attr.getQualifiedAttributeName() + "=" + attrVal);
+                }
+
+                if (!vertex.isPresent()) {
+                    vertex = findBySuperTypeAndQualifiedName(entityType.getTypeName(), attr.getQualifiedAttributeName(), attrVal);
+                }
+
+                if (vertex.isPresent()) {
+                    return vertex;
+                }
+            }
+        }
+
+        return Optional.absent();
+    }
+
+    Optional<AtlasVertex> resolveByUniqueAttribute(AtlasObjectId entityId) throws AtlasBaseException {
+        AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityId.getTypeName());
+
+        if (entityType == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), entityId.getTypeName());
+        }
+
+        final Map<String, Object> uniqueAttributes = entityId.getUniqueAttributes();
+        if (MapUtils.isNotEmpty(uniqueAttributes)) {
+            for (String attrName : uniqueAttributes.keySet()) {
+                AtlasStructType.AtlasAttribute attr = entityType.getAttribute(attrName);
+
+                if (attr.getAttributeDef().getIsUnique()) {
+                    Object attrVal = uniqueAttributes.get(attr.getName());
+
+                    if (attrVal == null) {
+                        continue;
+                    }
+
+                    Optional<AtlasVertex> vertex = findByTypeAndQualifiedName(entityId.getTypeName(), attr.getQualifiedAttributeName(), attrVal);
+
+                    if (!vertex.isPresent()) {
+                        vertex = findBySuperTypeAndQualifiedName(entityId.getTypeName(), attr.getQualifiedAttributeName(), attrVal);
+                    }
+
+                    if (vertex.isPresent()) {
+                        return vertex;
                     }
                 }
             }
@@ -132,6 +164,46 @@ public class UniqAttrBasedEntityResolver implements EntityResolver {
         return Optional.absent();
     }
 
+    Optional<AtlasVertex> findByTypeAndQualifiedName(String typeName, String qualifiedAttrName, Object attrVal) {
+        AtlasVertex vertex = null;
+        try {
+            vertex = graphHelper.findVertex(qualifiedAttrName, attrVal,
+                Constants.ENTITY_TYPE_PROPERTY_KEY, typeName,
+                Constants.STATE_PROPERTY_KEY, AtlasEntity.Status.ACTIVE
+                    .name());
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Found vertex by unique attribute and type {} {} ", qualifiedAttrName + "=" + attrVal, typeName);
+            }
+            if (vertex != null) {
+                return Optional.of(vertex);
+            }
+        } catch (EntityNotFoundException e) {
+            //Ignore if not found
+        }
+        return Optional.absent();
+    }
+
+    Optional<AtlasVertex> findBySuperTypeAndQualifiedName(String typeName, String qualifiedAttrName, Object attrVal) {
+        AtlasVertex vertex = null;
+        try {
+            vertex = graphHelper.findVertex(qualifiedAttrName, attrVal,
+                Constants.SUPER_TYPES_PROPERTY_KEY, typeName,
+                Constants.STATE_PROPERTY_KEY, AtlasEntity.Status.ACTIVE
+                    .name());
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Found vertex by unique attribute and supertype {} ", qualifiedAttrName + "=" + attrVal, typeName);
+            }
+            if (vertex != null) {
+                return Optional.of(vertex);
+            }
+        } catch (EntityNotFoundException e) {
+            //Ignore if not found
+        }
+        return Optional.absent();
+    }
+
     @Override
     public void cleanUp() {
         //Nothing to cleanup

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
index 546cd0c..6cbb602 100644
--- a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
@@ -71,6 +71,8 @@ import java.util.List;
 import java.util.Map;
 
 import static org.apache.atlas.TestUtils.COLUMNS_ATTR_NAME;
+import static org.apache.atlas.TestUtils.COLUMN_TYPE;
+import static org.apache.atlas.TestUtils.NAME;
 import static org.apache.atlas.TestUtils.TABLE_TYPE;
 import static org.apache.atlas.TestUtils.randomString;
 import static org.testng.Assert.assertEquals;
@@ -91,6 +93,10 @@ public class AtlasEntityStoreV1Test {
     @Inject
     MetadataService metadataService;
     
+    private Map<String, AtlasEntity> deptEntityMap;
+    private Map<String, AtlasEntity> dbEntityMap;
+    private Map<String, AtlasEntity> tableEntityMap;
+
     private AtlasEntity deptEntity;
     private AtlasEntity dbEntity;
     private AtlasEntity tableEntity;
@@ -105,9 +111,13 @@ public class AtlasEntityStoreV1Test {
         final AtlasTypesDef hiveTypesDef = TestUtilsV2.defineHiveTypes();
         typeDefStore.createTypesDef(hiveTypesDef);
         
-        deptEntity = TestUtilsV2.createDeptEg1();
-        dbEntity = TestUtilsV2.createDBEntity();
-        tableEntity = TestUtilsV2.createTableEntity(dbEntity.getGuid());
+        deptEntityMap = TestUtilsV2.createDeptEg1();
+        dbEntityMap = TestUtilsV2.createDBEntity();
+        tableEntityMap = TestUtilsV2.createTableEntity(dbEntityMap.keySet().iterator().next());
+
+        deptEntity = deptEntityMap.values().iterator().next();
+        dbEntity = dbEntityMap.values().iterator().next();
+        tableEntity = tableEntityMap.values().iterator().next();
     }
 
     @AfterClass
@@ -124,45 +134,46 @@ public class AtlasEntityStoreV1Test {
         ArrayVertexMapper arrVertexMapper = new ArrayVertexMapper(deleteHandler);
         MapVertexMapper mapVertexMapper = new MapVertexMapper(deleteHandler);
 
-        List<EntityResolver> entityResolvers = new ArrayList<>();
-        entityResolvers.add(new IDBasedEntityResolver());
-        entityResolvers.add(new UniqAttrBasedEntityResolver(typeRegistry));
-
-        EntityGraphDiscovery graphDiscovery = new AtlasEntityGraphDiscoveryV1(typeRegistry, entityResolvers);
 
         entityStore = new AtlasEntityStoreV1(new EntityGraphMapper(arrVertexMapper, mapVertexMapper, deleteHandler));
-        entityStore.init(typeRegistry, graphDiscovery);
+        entityStore.init(typeRegistry);
 
         RequestContextV1.clear();
     }
 
     @Test
     public void testCreate() throws Exception {
-        EntityMutationResponse response = entityStore.createOrUpdate(deptEntity);
+        EntityMutationResponse response = entityStore.createOrUpdate(deptEntityMap);
 
         validateMutationResponse(response, EntityMutations.EntityOperation.CREATE, 5);
-        AtlasEntityHeader deptEntity = response.getFirstEntityCreated();
+        AtlasEntityHeader deptEntity = response.getFirstCreatedEntityByTypeName(TestUtilsV2.DEPARTMENT_TYPE);
 
-        validateAttributes(deptEntity);
+        final Map<EntityMutations.EntityOperation, List<AtlasEntityHeader>> entitiesMutated = response.getEntitiesMutated();
+        List<AtlasEntityHeader> entitiesCreated = entitiesMutated.get(EntityMutations.EntityOperation.CREATE);
+
+        for (AtlasEntityHeader header : entitiesCreated) {
+            validateAttributes(deptEntityMap, header);
+        }
 
         //Create DB
-        EntityMutationResponse dbCreationResponse = entityStore.createOrUpdate(dbEntity);
+        EntityMutationResponse dbCreationResponse = entityStore.createOrUpdate(dbEntityMap);
         validateMutationResponse(dbCreationResponse, EntityMutations.EntityOperation.CREATE, 1);
 
-        AtlasEntityHeader dbEntity = dbCreationResponse.getFirstEntityCreated();
-        validateAttributes(dbEntity);
+        AtlasEntityHeader dbEntity = dbCreationResponse.getFirstCreatedEntityByTypeName(TestUtilsV2.DATABASE_TYPE);
+        validateAttributes(dbEntityMap, dbEntity);
 
         //Create Table
         //Update DB guid
         AtlasObjectId dbId = (AtlasObjectId) tableEntity.getAttribute("database");
         dbId.setGuid(dbEntity.getGuid());
+        tableEntityMap.put(dbId.getGuid(), dbEntityMap.values().iterator().next());
         tableEntity.setAttribute("database", dbId);
 
-        EntityMutationResponse tableCreationResponse = entityStore.createOrUpdate(tableEntity);
+        EntityMutationResponse tableCreationResponse = entityStore.createOrUpdate(tableEntityMap);
         validateMutationResponse(tableCreationResponse, EntityMutations.EntityOperation.CREATE, 1);
 
-        AtlasEntityHeader tableEntity = tableCreationResponse.getFirstEntityCreated();
-        validateAttributes(tableEntity);
+        AtlasEntityHeader tableEntity = tableCreationResponse.getFirstCreatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableEntityMap, tableEntity);
 
     }
 
@@ -171,74 +182,86 @@ public class AtlasEntityStoreV1Test {
         //clear state
         init();
 
-        AtlasEntity entityClone = new AtlasEntity(deptEntity);
+//        Map<String, AtlasEntity> entityCloneMap = new HashMap<>();
+//        AtlasEntity entityClone = new AtlasEntity(deptEntity);
+//        List<AtlasObjectId> employees = (List<AtlasObjectId>) entityClone.getAttribute("employees");
+//        AtlasEntity entityRemoved = clearSubOrdinates(employees, 1);
+//        entityClone.setAttribute("employees", employees);
+//        EntityMutationResponse response = entityStore.createOrUpdate(entityCloneMap);
+//
+//        validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 5);
+//        AtlasEntityHeader deptEntity = response.getFirstEntityUpdated();
+//        Assert.assertEquals(((List<AtlasEntity>)(((List<AtlasEntity>) deptEntity.getAttribute("employees")).get(1).getAttribute("subordinates"))).size(), 1);
+//
+//        init();
+//        //add  entity back
+//        addSubordinate(employees.get(1), entityRemoved);
+//        response = entityStore.createOrUpdate(entityCloneMap);
+//        validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 5);
+//        deptEntity = response.getFirstEntityUpdated();
+//        validateAttributes(deptEntity);
 
-        List<AtlasEntity> employees = (List<AtlasEntity>) entityClone.getAttribute("employees");
 
-        AtlasEntity entityRemoved = clearSubOrdinates(employees, 1);
-        entityClone.setAttribute("employees", employees);
-        EntityMutationResponse response = entityStore.createOrUpdate(entityClone);
-        
-        validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 5);
-        AtlasEntityHeader deptEntity = response.getFirstEntityUpdated();
-        Assert.assertEquals(((List<AtlasEntity>)(((List<AtlasEntity>) deptEntity.getAttribute("employees")).get(1).getAttribute("subordinates"))).size(), 1);
-
-        init();
-        //add  entity back
-        addSubordinate(employees.get(1), entityRemoved);
-        response = entityStore.createOrUpdate(entityClone);
-        validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 5);
-        deptEntity = response.getFirstEntityUpdated();
-        validateAttributes(deptEntity);
+        Map<String, AtlasEntity> tableUpdatedMap = new HashMap<>();
+        tableUpdatedMap.put(dbEntity.getGuid(), dbEntity);
 
         //test array of class with id
-        final List<AtlasEntity> columns = new ArrayList<>();
+        final List<AtlasObjectId> columns = new ArrayList<>();
 
         AtlasEntity col1 = TestUtilsV2.createColumnEntity(tableEntity.getGuid());
         col1.setAttribute(TestUtilsV2.NAME, "col1");
-        columns.add(col1);
+        columns.add(col1.getAtlasObjectId());
+        tableUpdatedMap.put(col1.getGuid(), col1);
+
         AtlasEntity tableUpdated = new AtlasEntity(tableEntity);
         tableUpdated.setAttribute(TestUtilsV2.COLUMNS_ATTR_NAME, columns);
+        tableUpdatedMap.put(tableUpdated.getGuid(), tableUpdated);
 
         init();
-        response = entityStore.createOrUpdate(tableUpdated);
-        AtlasEntityHeader updatedTable = response.getFirstEntityUpdated();
-        validateAttributes(updatedTable);
+        EntityMutationResponse response = entityStore.createOrUpdate(tableUpdatedMap);
+        AtlasEntityHeader updatedTable = response.getFirstUpdatedEntityByTypeName(tableUpdated.getTypeName());
+        validateAttributes(tableUpdatedMap, updatedTable);
 
         //Complete update. Add  array elements - col3,col4
         AtlasEntity col3 = TestUtilsV2.createColumnEntity(tableEntity.getGuid());
         col1.setAttribute(TestUtilsV2.NAME, "col3");
-        columns.add(col3);
+        columns.add(col3.getAtlasObjectId());
+        tableUpdatedMap.put(col3.getGuid(), col3);
 
         AtlasEntity col4 = TestUtilsV2.createColumnEntity(tableEntity.getGuid());
         col1.setAttribute(TestUtilsV2.NAME, "col4");
-        columns.add(col4);
+        columns.add(col4.getAtlasObjectId());
+        tableUpdatedMap.put(col4.getGuid(), col4);
 
         tableUpdated.setAttribute(COLUMNS_ATTR_NAME, columns);
         init();
-        response = entityStore.createOrUpdate(tableUpdated);
-        updatedTable = response.getFirstEntityUpdated();
-        validateAttributes(updatedTable);
+        response = entityStore.createOrUpdate(tableUpdatedMap);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(tableUpdated.getTypeName());
+        validateAttributes(tableUpdatedMap, updatedTable);
 
         //Swap elements
+        tableUpdatedMap.clear();
         columns.clear();
-        columns.add(col4);
-        columns.add(col3);
-
         tableUpdated.setAttribute(COLUMNS_ATTR_NAME, columns);
+        tableUpdatedMap.put(tableUpdated.getGuid(), tableUpdated);
+        tableUpdatedMap.put(col3.getGuid(), col3);
+        tableUpdatedMap.put(col4.getGuid(), col4);
+        columns.add(col4.getAtlasObjectId());
+        columns.add(col3.getAtlasObjectId());
+
         init();
-        response = entityStore.createOrUpdate(tableUpdated);
-        updatedTable = response.getFirstEntityUpdated();
-        Assert.assertEquals(((List<AtlasEntity>) updatedTable.getAttribute(COLUMNS_ATTR_NAME)).size(), 2);
+        response = entityStore.createOrUpdate(tableUpdatedMap);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(tableUpdated.getTypeName());
+        Assert.assertEquals(((List<AtlasObjectId>) updatedTable.getAttribute(COLUMNS_ATTR_NAME)).size(), 2);
 
         assertEquals(response.getEntitiesByOperation(EntityMutations.EntityOperation.DELETE).size(), 1);  //col1 is deleted
 
         //Update array column to null
         tableUpdated.setAttribute(COLUMNS_ATTR_NAME, null);
         init();
-        response = entityStore.createOrUpdate(tableUpdated);
-        updatedTable = response.getFirstEntityUpdated();
-        validateAttributes(updatedTable);
+        response = entityStore.createOrUpdate(tableUpdatedMap);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(tableUpdated.getTypeName());
+        validateAttributes(tableUpdatedMap, updatedTable);
         assertEquals(response.getEntitiesByOperation(EntityMutations.EntityOperation.DELETE).size(), 2);
 
     }
@@ -246,6 +269,7 @@ public class AtlasEntityStoreV1Test {
     @Test(dependsOnMethods = "testCreate")
     public void testUpdateEntityWithMap() throws Exception {
 
+        final Map<String, AtlasEntity> tableCloneMap = new HashMap<>();
         final AtlasEntity tableClone = new AtlasEntity(tableEntity);
         final Map<String, AtlasStruct> partsMap = new HashMap<>();
         partsMap.put("part0", new AtlasStruct(TestUtils.PARTITION_STRUCT_TYPE,
@@ -255,11 +279,13 @@ public class AtlasEntityStoreV1Test {
 
         
         tableClone.setAttribute("partitionsMap", partsMap);
+        tableCloneMap.put(tableClone.getGuid(), tableClone);
+
 
         init();
-        EntityMutationResponse response = entityStore.createOrUpdate(tableClone);
-        final AtlasEntityHeader tableDefinition1 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition1);
+        EntityMutationResponse response = entityStore.createOrUpdate(tableCloneMap);
+        final AtlasEntityHeader tableDefinition1 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition1);
                 
         Assert.assertTrue(partsMap.get("part0").equals(((Map<String, AtlasStruct>) tableDefinition1.getAttribute("partitionsMap")).get("part0")));
 
@@ -271,9 +297,9 @@ public class AtlasEntityStoreV1Test {
         tableClone.setAttribute("partitionsMap", partsMap);
 
         init();
-        response = entityStore.createOrUpdate(tableClone);
-        AtlasEntityHeader tableDefinition2 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition2);
+        response = entityStore.createOrUpdate(tableCloneMap);
+        AtlasEntityHeader tableDefinition2 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition2);
 
         assertEquals(((Map<String, AtlasStruct>) tableDefinition2.getAttribute("partitionsMap")).size(), 2);
         Assert.assertTrue(partsMap.get("part1").equals(((Map<String, AtlasStruct>) tableDefinition2.getAttribute("partitionsMap")).get("part1")));
@@ -287,9 +313,9 @@ public class AtlasEntityStoreV1Test {
         tableClone.setAttribute("partitionsMap", partsMap);
 
         init();
-        response = entityStore.createOrUpdate(tableClone);
-        AtlasEntityHeader tableDefinition3 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition3);
+        response = entityStore.createOrUpdate(tableCloneMap);
+        AtlasEntityHeader tableDefinition3 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition3);
 
         assertEquals(((Map<String, AtlasStruct>) tableDefinition3.getAttribute("partitionsMap")).size(), 2);
         Assert.assertNull(((Map<String, AtlasStruct>) tableDefinition3.getAttribute("partitionsMap")).get("part0"));
@@ -299,9 +325,9 @@ public class AtlasEntityStoreV1Test {
         init();
         AtlasStruct partition2 = partsMap.get("part2");
         partition2.setAttribute(TestUtilsV2.NAME, "test2Updated");
-        response = entityStore.createOrUpdate(tableClone);
-        final AtlasEntityHeader tableDefinition4 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition4);
+        response = entityStore.createOrUpdate(tableCloneMap);
+        final AtlasEntityHeader tableDefinition4 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition4);
 
         assertEquals(((Map<String, AtlasStruct>) tableDefinition4.getAttribute("partitionsMap")).size(), 2);
         Assert.assertNull(((Map<String, AtlasStruct>) tableDefinition4.getAttribute("partitionsMap")).get("part0"));
@@ -312,16 +338,23 @@ public class AtlasEntityStoreV1Test {
 
         //Test map pointing to a class
 
-        final Map<String, AtlasEntity> columnsMap = new HashMap<>();
+        final Map<String, AtlasObjectId> columnsMap = new HashMap<>();
+
+        Map<String, AtlasEntity> col0TypeMap = new HashMap<>();
         AtlasEntity col0Type = new AtlasEntity(TestUtilsV2.COLUMN_TYPE,
             new HashMap<String, Object>() {{
                 put(TestUtilsV2.NAME, "test1");
                 put("type", "string");
                 put("table", new AtlasObjectId(TABLE_TYPE, tableDefinition1.getGuid()));
             }});
+
+        col0TypeMap.put(col0Type.getGuid(), col0Type);
+
+
         init();
-        entityStore.createOrUpdate(col0Type);
+        entityStore.createOrUpdate(col0TypeMap);
 
+        Map<String, AtlasEntity> col1TypeMap = new HashMap<>();
         AtlasEntity col1Type = new AtlasEntity(TestUtils.COLUMN_TYPE,
             new HashMap<String, Object>() {{
                 put(TestUtilsV2.NAME, "test2");
@@ -330,43 +363,50 @@ public class AtlasEntityStoreV1Test {
             }});
 
         init();
-        entityStore.createOrUpdate(col1Type);
+        col1TypeMap.put(col1Type.getGuid(), col1Type);
+        entityStore.createOrUpdate(col1TypeMap);
+
+        AtlasObjectId col0Id = new AtlasObjectId(col0Type.getTypeName(), col0Type.getGuid());
+        AtlasObjectId col1Id = new AtlasObjectId(col1Type.getTypeName(), col1Type.getGuid());
+
+        columnsMap.put("col0", col0Id);
+        columnsMap.put("col1", col1Id);
+        tableCloneMap.put(col0Type.getGuid(), col0Type);
+        tableCloneMap.put(col1Type.getGuid(), col1Type);
 
-        columnsMap.put("col0", col0Type);
-        columnsMap.put("col1", col1Type);
         tableClone.setAttribute(TestUtils.COLUMNS_MAP, columnsMap);
 
         init();
-        response = entityStore.createOrUpdate(tableClone);
-        AtlasEntityHeader tableDefinition5 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition5);
+        response = entityStore.createOrUpdate(tableCloneMap);
+        AtlasEntityHeader tableDefinition5 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition5);
 
         //Swap elements
         columnsMap.clear();
-        columnsMap.put("col0", col1Type);
-        columnsMap.put("col1", col0Type);
+        columnsMap.put("col0", col1Id);
+        columnsMap.put("col1", col0Id);
 
         tableClone.setAttribute(TestUtils.COLUMNS_MAP, columnsMap);
         init();
-        response = entityStore.createOrUpdate(tableClone);
-        AtlasEntityHeader tableDefinition6 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition6);
+        response = entityStore.createOrUpdate(tableCloneMap);
+        AtlasEntityHeader tableDefinition6 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition6);
 
         //Drop the first key and change the class type as well to col0
         columnsMap.clear();
-        columnsMap.put("col0", col0Type);
+        columnsMap.put("col0", col0Id);
 
         init();
-        response = entityStore.createOrUpdate(tableClone);
-        AtlasEntityHeader tableDefinition7 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition7);
+        response = entityStore.createOrUpdate(tableCloneMap);
+        AtlasEntityHeader tableDefinition7 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition7);
 
         //Clear state
         tableClone.setAttribute(TestUtils.COLUMNS_MAP, null);
         init();
-        response = entityStore.createOrUpdate(tableClone);
-        AtlasEntityHeader tableDefinition8 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition8);
+        response = entityStore.createOrUpdate(tableCloneMap);
+        AtlasEntityHeader tableDefinition8 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition8);
     }
 
     @Test(dependsOnMethods = "testCreate")
@@ -374,17 +414,19 @@ public class AtlasEntityStoreV1Test {
         //clear state
         init();
 
+        Map<String, AtlasEntity> entityCloneMap = new HashMap<>();
         AtlasEntity entityClone = new AtlasEntity(tableEntity);
+        entityCloneMap.put(entityClone.getGuid(), entityClone);
 
         //Add a new entry
         Map<String, String> paramsMap = (Map<String, String>) entityClone.getAttribute("parametersMap");
         paramsMap.put("newParam", "value");
         entityClone.setAttribute("parametersMap", paramsMap);
 
-        EntityMutationResponse response = entityStore.createOrUpdate(entityClone);
+        EntityMutationResponse response = entityStore.createOrUpdate(entityCloneMap);
         validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 1);
-        AtlasEntityHeader tableEntity = response.getFirstEntityUpdated();
-        validateAttributes(tableEntity);
+        AtlasEntityHeader tableEntity = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(entityCloneMap, tableEntity);
 
         //clear state
         init();
@@ -393,10 +435,10 @@ public class AtlasEntityStoreV1Test {
         paramsMap.remove("key1");
         entityClone.setAttribute("parametersMap", paramsMap);
 
-        response = entityStore.createOrUpdate(entityClone);
+        response = entityStore.createOrUpdate(entityCloneMap);
         validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 1);
-        tableEntity = response.getFirstEntityUpdated();
-        validateAttributes(tableEntity);
+        tableEntity = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(entityCloneMap, tableEntity);
     }
 
     @Test(dependsOnMethods = "testCreate")
@@ -412,10 +454,10 @@ public class AtlasEntityStoreV1Test {
         List<AtlasStruct> partitions = new ArrayList<AtlasStruct>(){{ add(partition1); add(partition2); }};
         tableEntity.setAttribute("partitions", partitions);
 
-        EntityMutationResponse response = entityStore.createOrUpdate(tableEntity);
-        AtlasEntityHeader tableDefinition = response.getFirstEntityUpdated();
+        EntityMutationResponse response = entityStore.createOrUpdate(tableEntityMap);
+        AtlasEntityHeader tableDefinition = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
 
-        validateAttributes(tableDefinition);
+        validateAttributes(tableEntityMap, tableDefinition);
 
         //add a new element to array of struct
         init();
@@ -423,25 +465,25 @@ public class AtlasEntityStoreV1Test {
         partition3.setAttribute(TestUtilsV2.NAME, "part3");
         partitions.add(partition3);
         tableEntity.setAttribute("partitions", partitions);
-        response = entityStore.createOrUpdate(tableEntity);
-        tableDefinition = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition);
+        response = entityStore.createOrUpdate(tableEntityMap);
+        tableDefinition = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableEntityMap, tableDefinition);
 
         //remove one of the struct values
         init();
         partitions.remove(1);
         tableEntity.setAttribute("partitions", partitions);
-        response = entityStore.createOrUpdate(tableEntity);
-        tableDefinition = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition);
+        response = entityStore.createOrUpdate(tableEntityMap);
+        tableDefinition = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableEntityMap, tableDefinition);
 
         //Update struct value within array of struct
         init();
         partitions.get(0).setAttribute(TestUtilsV2.NAME, "part4");
         tableEntity.setAttribute("partitions", partitions);
-        response = entityStore.createOrUpdate(tableEntity);
-        tableDefinition = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition);
+        response = entityStore.createOrUpdate(tableEntityMap);
+        tableDefinition = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableEntityMap, tableDefinition);
 
 
         //add a repeated element to array of struct
@@ -450,17 +492,17 @@ public class AtlasEntityStoreV1Test {
         partition4.setAttribute(TestUtilsV2.NAME, "part4");
         partitions.add(partition4);
         tableEntity.setAttribute("partitions", partitions);
-        response = entityStore.createOrUpdate(tableEntity);
-        tableDefinition = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition);
+        response = entityStore.createOrUpdate(tableEntityMap);
+        tableDefinition = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableEntityMap, tableDefinition);
 
         // Remove all elements. Should set array attribute to null
         init();
         partitions.clear();
         tableEntity.setAttribute("partitions", partitions);
-        response = entityStore.createOrUpdate(tableEntity);
-        tableDefinition = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition);
+        response = entityStore.createOrUpdate(tableEntityMap);
+        tableDefinition = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableEntityMap, tableDefinition);
     }
 
 
@@ -468,53 +510,57 @@ public class AtlasEntityStoreV1Test {
     public void testStructs() throws Exception {
         init();
 
+        Map<String, AtlasEntity> tableCloneMap = new HashMap<>();
         AtlasEntity tableClone = new AtlasEntity(tableEntity);
         AtlasStruct serdeInstance = new AtlasStruct(TestUtils.SERDE_TYPE);
         serdeInstance.setAttribute(TestUtilsV2.NAME, "serde1Name");
         serdeInstance.setAttribute("serde", "test");
         serdeInstance.setAttribute("description", "testDesc");
         tableClone.setAttribute("serde1", serdeInstance);
-        tableClone.setAttribute("database", dbEntity);
+        tableClone.setAttribute("database", new AtlasObjectId(dbEntity.getTypeName(), new HashMap<String, Object>() {{
+            put(TestUtilsV2.NAME, dbEntity.getAttribute(TestUtilsV2.NAME));
+        }}));
+
+        tableCloneMap.put(tableClone.getGuid(), tableClone);
 
-        EntityMutationResponse response = entityStore.createOrUpdate(tableClone);
-        AtlasEntityHeader tableDefinition1 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition1);
+        EntityMutationResponse response = entityStore.createOrUpdate(tableCloneMap);
+        AtlasEntityHeader tableDefinition1 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition1);
 
         //update struct attribute
         init();
         serdeInstance.setAttribute("serde", "testUpdated");
-        response = entityStore.createOrUpdate(tableClone);
-        AtlasEntityHeader tableDefinition2 = response.getFirstEntityUpdated();
-        validateAttributes(tableDefinition2);
+        response = entityStore.createOrUpdate(tableCloneMap);
+        AtlasEntityHeader tableDefinition2 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
+        validateAttributes(tableCloneMap, tableDefinition2);
 
         //set to null
         init();
         tableClone.setAttribute("description", null);
-        response = entityStore.createOrUpdate(tableClone);
-        AtlasEntityHeader tableDefinition3 = response.getFirstEntityUpdated();
+        response = entityStore.createOrUpdate(tableCloneMap);
+        AtlasEntityHeader tableDefinition3 = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
         Assert.assertNull(tableDefinition3.getAttribute("description"));
-        validateAttributes(tableDefinition3);
+        validateAttributes(tableCloneMap, tableDefinition3);
     }
 
-    private AtlasEntity clearSubOrdinates(List<AtlasEntity> employees, int index) {
-
-        AtlasEntity ret = null;
-        List<AtlasEntity> subOrdinates = (List<AtlasEntity>) employees.get(index).getAttribute("subordinates");
-        List<AtlasEntity> subOrdClone = new ArrayList<>(subOrdinates);
-        ret = subOrdClone.remove(index);
-
-        employees.get(index).setAttribute("subordinates", subOrdClone);
-        return ret;
-    }
-
-    private int addSubordinate(AtlasEntity manager, AtlasEntity employee) {
-        List<AtlasEntity> subOrdinates = (List<AtlasEntity>) manager.getAttribute("subordinates");
-        subOrdinates.add(employee);
-
-        manager.setAttribute("subordinates", subOrdinates);
-
-        return subOrdinates.size() - 1;
-    }
+//    private AtlasEntity clearSubOrdinates(List<AtlasObjectId> employees, int index) {
+//
+//        AtlasEntity ret = null;
+//        AtlasObjectId employee = employees.get(index);
+//        AtlasEntity subOrdClone = new ArrayList<>(subOrdinates);
+//        ret = subOrdClone.remove(index);
+//
+//        employees.get(index).setAttribute("subordinates", subOrdClone);
+//        return ret;
+//    }
+//
+//    private int addSubordinate(AtlasEntity manager, AtlasEntity employee) {
+//        List<AtlasEntity> subOrdinates = (List<AtlasEntity>) manager.getAttribute("subordinates");
+//        subOrdinates.add(employee);
+//
+//        manager.setAttribute("subordinates", subOrdinates);
+//        return subOrdinates.size() - 1;
+//    }
 
     private void validateMutationResponse(EntityMutationResponse response, EntityMutations.EntityOperation op, int expectedNumCreated) {
         List<AtlasEntityHeader> entitiesCreated = response.getEntitiesByOperation(op);
@@ -522,13 +568,13 @@ public class AtlasEntityStoreV1Test {
         Assert.assertEquals(entitiesCreated.size(), expectedNumCreated);
     }
 
-    private void validateAttributes(AtlasEntityHeader entity) throws AtlasBaseException, AtlasException {
+    private void validateAttributes(Map<String, AtlasEntity> entityMap, AtlasEntityHeader entity) throws AtlasBaseException, AtlasException {
         //TODO : Use the older API for get until new instance API is ready and validated
         ITypedReferenceableInstance instance = metadataService.getEntityDefinition(entity.getGuid());
-        assertAttributes(entity, instance);
+        assertAttributes(entityMap, entity, instance);
     }
 
-    private void assertAttributes(AtlasStruct entity, IInstance instance) throws AtlasBaseException, AtlasException {
+    private void assertAttributes(Map<String, AtlasEntity> entityMap, AtlasStruct entity, IInstance instance) throws AtlasBaseException, AtlasException {
         LOG.debug("Asserting type : " + entity.getTypeName());
         AtlasStructType entityType = (AtlasStructType) typeRegistry.getType(instance.getTypeName());
         for (String attrName : entity.getAttributes().keySet()) {
@@ -536,11 +582,11 @@ public class AtlasEntityStoreV1Test {
             Object expected = instance.get(attrName);
 
             AtlasType attrType = entityType.getAttributeType(attrName);
-            assertAttribute(actual, expected, attrType, attrName);
+            assertAttribute(entityMap, actual, expected, attrType, attrName);
         }
     }
 
-    private void assertAttribute(Object actual, Object expected, AtlasType attributeType, String attrName) throws AtlasBaseException, AtlasException {
+    private void assertAttribute(Map<String, AtlasEntity> actualEntityMap, Object actual, Object expected, AtlasType attributeType, String attrName) throws AtlasBaseException, AtlasException {
         LOG.debug("Asserting attribute : " + attrName);
 
         switch(attributeType.getTypeCategory()) {
@@ -550,9 +596,16 @@ public class AtlasEntityStoreV1Test {
                 Assert.assertTrue(AtlasEntity.isAssigned(guid));
             } else {
                 ReferenceableInstance expectedInstance = (ReferenceableInstance) expected;
-                AtlasEntity actualInstance = (AtlasEntity) actual;
-                if ( actualInstance != null) {
-                    assertAttributes(actualInstance, expectedInstance);
+                if (actual instanceof AtlasObjectId) {
+                    AtlasEntity actualEntity = actualEntityMap.get(((AtlasObjectId) actual).getGuid());
+                    if (actualEntity != null) {
+                        assertAttributes(actualEntityMap, actualEntity, expectedInstance);
+                    }
+                } else {
+                    AtlasEntity actualInstance = (AtlasEntity) actual;
+                    if (actualInstance != null) {
+                        assertAttributes(actualEntityMap , actualInstance, expectedInstance);
+                    }
                 }
             }
             break;
@@ -575,7 +628,7 @@ public class AtlasEntityStoreV1Test {
             if (expectedMap != null && actualMap != null) {
                 Assert.assertEquals(actualMap.size(), expectedMap.size());
                 for (Object key : actualMap.keySet()) {
-                    assertAttribute(actualMap.get(key), expectedMap.get(key), valueType, attrName);
+                    assertAttribute(actualEntityMap, actualMap.get(key), expectedMap.get(key), valueType, attrName);
                 }
             }
             break;
@@ -588,14 +641,14 @@ public class AtlasEntityStoreV1Test {
             if (CollectionUtils.isNotEmpty(actualList)) {
                 //actual list could have deleted entities . Hence size may not match.
                 for (int i = 0; i < actualList.size(); i++) {
-                    assertAttribute(actualList.get(i), expectedList.get(i), elemType, attrName);
+                    assertAttribute(actualEntityMap, actualList.get(i), expectedList.get(i), elemType, attrName);
                 }
             }
             break;
         case STRUCT:
             StructInstance structInstance = (StructInstance) expected;
             AtlasStruct newStructVal = (AtlasStruct) actual;
-            assertAttributes(newStructVal, structInstance);
+            assertAttributes(actualEntityMap, newStructVal, structInstance);
             break;
         default:
             Assert.fail("Unknown type category");
@@ -607,17 +660,21 @@ public class AtlasEntityStoreV1Test {
 
         init();
         //Create new db instance
-        final AtlasEntity databaseInstance = TestUtilsV2.createDBEntity();
+        final Map<String, AtlasEntity> databaseInstance = TestUtilsV2.createDBEntity();
 
         EntityMutationResponse response = entityStore.createOrUpdate(databaseInstance);
-        final AtlasEntityHeader dbCreated = response.getFirstEntityCreated();
+        final AtlasEntityHeader dbCreated = response.getFirstCreatedEntityByTypeName(TestUtilsV2.DATABASE_TYPE);
 
         init();
+        Map<String, AtlasEntity> tableCloneMap = new HashMap<>();
         AtlasEntity tableClone = new AtlasEntity(tableEntity);
         tableClone.setAttribute("database", new AtlasObjectId(TestUtils.DATABASE_TYPE, dbCreated.getGuid()));
-        response = entityStore.createOrUpdate(tableClone);
-        final AtlasEntityHeader tableDefinition = response.getFirstEntityUpdated();
 
+        tableCloneMap.put(dbCreated.getGuid(), databaseInstance.values().iterator().next());
+        tableCloneMap.put(tableClone.getGuid(), tableClone);
+
+        response = entityStore.createOrUpdate(tableCloneMap);
+        final AtlasEntityHeader tableDefinition = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.TABLE_TYPE);
         Assert.assertNotNull(tableDefinition.getAttribute("database"));
         Assert.assertEquals(((AtlasObjectId) tableDefinition.getAttribute("database")).getGuid(), dbCreated.getGuid());
     }
@@ -625,9 +682,9 @@ public class AtlasEntityStoreV1Test {
     @Test
     public void testCheckOptionalAttrValueRetention() throws Exception {
 
-        AtlasEntity dbEntity = TestUtilsV2.createDBEntity();
-        EntityMutationResponse response = entityStore.createOrUpdate(dbEntity);
-        AtlasEntityHeader firstEntityCreated = response.getFirstEntityCreated();
+        Map<String, AtlasEntity> dbEntityMap = TestUtilsV2.createDBEntity();
+        EntityMutationResponse response = entityStore.createOrUpdate(dbEntityMap);
+        AtlasEntityHeader firstEntityCreated = response.getFirstCreatedEntityByTypeName(TestUtilsV2.DATABASE_TYPE);
 
         //The optional boolean attribute should have a non-null value
         final String isReplicatedAttr = "isReplicated";
@@ -638,13 +695,16 @@ public class AtlasEntityStoreV1Test {
 
         //Update to true
         init();
+        AtlasEntity dbEntity = dbEntityMap.values().iterator().next();
         dbEntity.setAttribute(isReplicatedAttr, Boolean.TRUE);
         //Update array
         final HashMap<String, String> params = new HashMap<String, String>() {{ put("param1", "val1"); put("param2", "val2"); }};
         dbEntity.setAttribute(paramsAttr, params);
         //Complete update
-        response = entityStore.createOrUpdate(dbEntity);
-        AtlasEntityHeader firstEntityUpdated = response.getFirstEntityUpdated();
+
+        dbEntityMap.put(dbEntity.getGuid(), dbEntity);
+        response = entityStore.createOrUpdate(dbEntityMap);
+        AtlasEntityHeader firstEntityUpdated = response.getFirstUpdatedEntityByTypeName(TestUtilsV2.DATABASE_TYPE);
 
         Assert.assertNotNull(firstEntityUpdated.getAttribute(isReplicatedAttr));
         Assert.assertEquals(firstEntityUpdated.getAttribute(isReplicatedAttr), Boolean.TRUE);
@@ -684,6 +744,8 @@ public class AtlasEntityStoreV1Test {
         typeDefStore.createEntityDef(typeDefinition);
 
         //verify that entity can be created with reserved characters in string value, array value and map key and value
+        Map<String, AtlasEntity> entityCloneMap = new HashMap<>();
+
         AtlasEntity entity = new AtlasEntity();
         entity.setAttribute(strAttrName, randomStrWithReservedChars());
         entity.setAttribute(arrayAttrName, new String[]{randomStrWithReservedChars()});
@@ -691,9 +753,10 @@ public class AtlasEntityStoreV1Test {
             put(randomStrWithReservedChars(), randomStrWithReservedChars());
         }});
 
-        final EntityMutationResponse response = entityStore.createOrUpdate(entity);
+        entityCloneMap.put(entity.getGuid(), entity);
+        final EntityMutationResponse response = entityStore.createOrUpdate(entityCloneMap);
         final AtlasEntityHeader firstEntityCreated = response.getFirstEntityCreated();
-        validateAttributes(firstEntityCreated);
+        validateAttributes(entityCloneMap, firstEntityCreated);
 
 
         //Verify that search with reserved characters works - for string attribute
@@ -711,11 +774,12 @@ public class AtlasEntityStoreV1Test {
     @Test(expectedExceptions = AtlasBaseException.class)
     public void testCreateRequiredAttrNull() throws Exception {
         //Update required attribute
-
+        Map<String, AtlasEntity> tableCloneMap = new HashMap<>();
         AtlasEntity tableEntity = new AtlasEntity(TestUtilsV2.TABLE_TYPE);
         tableEntity.setAttribute(TestUtilsV2.NAME, "table_" + TestUtils.randomString());
+        tableCloneMap.put(tableEntity.getGuid(), tableEntity);
 
-        entityStore.createOrUpdate(tableEntity);
+        entityStore.createOrUpdate(tableCloneMap);
         Assert.fail("Expected exception while creating with required attribute null");
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasArrayFormatConverter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasArrayFormatConverter.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasArrayFormatConverter.java
index e3b4efa..aa14aff 100644
--- a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasArrayFormatConverter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasArrayFormatConverter.java
@@ -38,7 +38,7 @@ public class AtlasArrayFormatConverter extends AtlasAbstractFormatConverter {
     }
 
     @Override
-    public Collection fromV1ToV2(Object v1Obj, AtlasType type) throws AtlasBaseException {
+    public Collection fromV1ToV2(Object v1Obj, AtlasType type, ConverterContext ctx) throws AtlasBaseException {
         Collection ret = null;
 
         if (v1Obj != null) {
@@ -57,7 +57,7 @@ public class AtlasArrayFormatConverter extends AtlasAbstractFormatConverter {
             Collection           v1List        = (Collection) v1Obj;
 
             for (Object v1Elem : v1List) {
-                Object convertedVal = elemConverter.fromV1ToV2(v1Elem, elemType);
+                Object convertedVal = elemConverter.fromV1ToV2(v1Elem, elemType, ctx);
 
                 ret.add(convertedVal);
             }
@@ -67,7 +67,7 @@ public class AtlasArrayFormatConverter extends AtlasAbstractFormatConverter {
     }
 
     @Override
-    public Collection fromV2ToV1(Object v2Obj, AtlasType type) throws AtlasBaseException {
+    public Collection fromV2ToV1(Object v2Obj, AtlasType type, ConverterContext ctx) throws AtlasBaseException {
         Collection ret = null;
 
         if (v2Obj != null) {
@@ -86,7 +86,7 @@ public class AtlasArrayFormatConverter extends AtlasAbstractFormatConverter {
             Collection           v2List        = (Collection) v2Obj;
 
             for (Object v2Elem : v2List) {
-                Object convertedVal = elemConverter.fromV2ToV1(v2Elem, elemType);
+                Object convertedVal = elemConverter.fromV2ToV1(v2Elem, elemType, ctx);
 
                 ret.add(convertedVal);
             }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasClassificationFormatConverter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasClassificationFormatConverter.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasClassificationFormatConverter.java
index da71c31..dc740f5 100644
--- a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasClassificationFormatConverter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasClassificationFormatConverter.java
@@ -40,7 +40,7 @@ public class AtlasClassificationFormatConverter extends AtlasStructFormatConvert
     }
 
     @Override
-    public AtlasClassification fromV1ToV2(Object v1Obj, AtlasType type) throws AtlasBaseException {
+    public AtlasClassification fromV1ToV2(Object v1Obj, AtlasType type, ConverterContext ctx) throws AtlasBaseException {
         AtlasClassification ret = null;
 
         if (v1Obj != null) {
@@ -51,7 +51,7 @@ public class AtlasClassificationFormatConverter extends AtlasStructFormatConvert
                 final Map v1Attribs = (Map) v1Map.get(ATTRIBUTES_PROPERTY_KEY);
 
                 if (MapUtils.isNotEmpty(v1Attribs)) {
-                    ret = new AtlasClassification(type.getTypeName(), fromV1ToV2(classificationType, v1Attribs));
+                    ret = new AtlasClassification(type.getTypeName(), fromV1ToV2(classificationType, v1Attribs, ctx));
                 } else {
                     ret = new AtlasClassification(type.getTypeName());
                 }
@@ -65,7 +65,7 @@ public class AtlasClassificationFormatConverter extends AtlasStructFormatConvert
                     LOG.error("IStruct.getValuesMap() failed", excp);
                 }
 
-                ret = new AtlasClassification(type.getTypeName(), fromV1ToV2(classificationType, v1Attribs));
+                ret = new AtlasClassification(type.getTypeName(), fromV1ToV2(classificationType, v1Attribs, ctx));
             } else {
                 throw new AtlasBaseException(AtlasErrorCode.UNEXPECTED_TYPE, "Map or IStruct",
                                              v1Obj.getClass().getCanonicalName());

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java
index bbfcc59..8f85052 100644
--- a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java
@@ -53,7 +53,7 @@ public class AtlasEntityFormatConverter extends AtlasStructFormatConverter {
     }
 
     @Override
-    public Object fromV1ToV2(Object v1Obj, AtlasType type) throws AtlasBaseException {
+    public Object fromV1ToV2(Object v1Obj, AtlasType type, ConverterContext context) throws AtlasBaseException {
         Object ret = null;
 
         if (v1Obj != null) {
@@ -67,13 +67,15 @@ public class AtlasEntityFormatConverter extends AtlasStructFormatConverter {
                 IReferenceableInstance entity    = (IReferenceableInstance) v1Obj;
                 Map<String, Object>    v1Attribs = null;
 
+                ret = new AtlasObjectId(entity.getTypeName(), entity.getId()._getId());
+
                 try {
                     v1Attribs = entity.getValuesMap();
                 } catch (AtlasException excp) {
                     LOG.error("IReferenceableInstance.getValuesMap() failed", excp);
                 }
 
-                AtlasEntityWithAssociations ret1 =  new AtlasEntityWithAssociations(entity.getTypeName(), super.fromV1ToV2(entityType, v1Attribs));
+                AtlasEntityWithAssociations ret1 =  new AtlasEntityWithAssociations(entity.getTypeName(), super.fromV1ToV2(entityType, v1Attribs, context));
                 ret1.setGuid(entity.getId()._getId());
                 ret1.setStatus(convertState(entity.getId().getState()));
                 AtlasSystemAttributes systemAttributes = entity.getSystemAttributes();
@@ -90,16 +92,17 @@ public class AtlasEntityFormatConverter extends AtlasStructFormatConverter {
                     for (String traitName : entity.getTraits()) {
                         IStruct             trait          = entity.getTrait(traitName);
                         AtlasType           classifiType   = typeRegistry.getType(traitName);
-                        AtlasClassification classification = (AtlasClassification) traitConverter.fromV1ToV2(trait, classifiType);
+                        AtlasClassification classification = (AtlasClassification) traitConverter.fromV1ToV2(trait, classifiType, context);
 
                         classifications.add(classification);
                     }
 
                     ret1.setClassifications(classifications);
                 }
-                ret = ret1;
+
+                context.addEntity(ret1);
             } else {
-                throw new AtlasBaseException(AtlasErrorCode.UNEXPECTED_TYPE, "Id or IReferenceableInstance",
+                throw new AtlasBaseException(AtlasErrorCode.UNEXPECTED_TYPE, "IReferenceableInstance",
                                              v1Obj.getClass().getCanonicalName());
             }
         }
@@ -116,7 +119,7 @@ public class AtlasEntityFormatConverter extends AtlasStructFormatConverter {
     }
 
     @Override
-    public Object fromV2ToV1(Object v2Obj, AtlasType type) throws AtlasBaseException {
+    public Object fromV2ToV1(Object v2Obj, AtlasType type, ConverterContext context) throws AtlasBaseException {
         Object ret = null;
 
         if (v2Obj != null) {
@@ -136,15 +139,21 @@ public class AtlasEntityFormatConverter extends AtlasStructFormatConverter {
                 if (MapUtils.isEmpty(v2Attribs)) {
                     ret = new Id(idStr, 0, typeName);
                 } else {
-                    ret = new Referenceable(idStr, typeName, super.fromV2ToV1(entityType, v2Attribs));
+                    ret = new Referenceable(idStr, typeName, super.fromV2ToV1(entityType, v2Attribs, context));
                 }
             } else if (v2Obj instanceof AtlasEntity) {
                 AtlasEntity entity = (AtlasEntity) v2Obj;
 
                 ret = new Referenceable(entity.getGuid(), entity.getTypeName(),
-                                        fromV2ToV1(entityType, entity.getAttributes()));
+                                        fromV2ToV1(entityType, entity.getAttributes(), context));
+
             } else if (v2Obj instanceof AtlasObjectId) { // transient-id
-                ret = new Referenceable(((AtlasObjectId) v2Obj).getGuid(), type.getTypeName(), null);
+                AtlasEntity entity = context.getById(((AtlasObjectId) v2Obj).getGuid());
+                if ( entity == null) {
+                    throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "Could not find entity ",
+                        v2Obj.toString());
+                }
+                ret = this.fromV2ToV1(entity, typeRegistry.getType(((AtlasObjectId) v2Obj).getTypeName()), context);
             } else {
                 throw new AtlasBaseException(AtlasErrorCode.UNEXPECTED_TYPE, "Map or AtlasEntity or String",
                                              v2Obj.getClass().getCanonicalName());

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEnumFormatConverter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEnumFormatConverter.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEnumFormatConverter.java
index 4f22437..6d8e3ae 100644
--- a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEnumFormatConverter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEnumFormatConverter.java
@@ -30,12 +30,12 @@ public class AtlasEnumFormatConverter extends AtlasAbstractFormatConverter {
     }
 
     @Override
-    public Object fromV1ToV2(Object v1Obj, AtlasType type) throws AtlasBaseException {
+    public Object fromV1ToV2(Object v1Obj, AtlasType type, ConverterContext ctx) throws AtlasBaseException {
         return type.getNormalizedValue(v1Obj);
     }
 
     @Override
-    public Object fromV2ToV1(Object v2Obj, AtlasType type) throws AtlasBaseException {
+    public Object fromV2ToV1(Object v2Obj, AtlasType type, ConverterContext ctx) throws AtlasBaseException {
         return type.getNormalizedValue(v2Obj);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasFormatConverter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasFormatConverter.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasFormatConverter.java
index 079f3be..1272543 100644
--- a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasFormatConverter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasFormatConverter.java
@@ -20,12 +20,62 @@ package org.apache.atlas.web.adapters;
 
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.TypeCategory;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntityWithAssociations;
 import org.apache.atlas.type.AtlasType;
 
+import java.util.HashMap;
+import java.util.Map;
+
 public interface AtlasFormatConverter {
-    Object fromV1ToV2(Object v1Obj, AtlasType type) throws AtlasBaseException;
+    Object fromV1ToV2(Object v1Obj, AtlasType type, ConverterContext context) throws AtlasBaseException;
 
-    Object fromV2ToV1(Object v2Obj, AtlasType type) throws AtlasBaseException;
+    Object fromV2ToV1(Object v2Obj, AtlasType type, ConverterContext context) throws AtlasBaseException;
 
     TypeCategory getTypeCategory();
+
+    public static class ConverterContext {
+
+        private Map<String, AtlasEntityWithAssociations> entities = null;
+
+        public void addEntity(AtlasEntityWithAssociations entity) {
+            if (entities == null) {
+                entities = new HashMap<>();
+            }
+            entities.put(entity.getGuid(), entity);
+        }
+
+        public void addEntity(AtlasEntity entity) {
+            if (entities == null) {
+                entities = new HashMap<>();
+            }
+            entities.put(entity.getGuid(), new AtlasEntityWithAssociations(entity));
+        }
+
+        public boolean exists(AtlasEntityWithAssociations entity) {
+            return entities != null ? entities.containsKey(entity.getGuid()) : false;
+        }
+
+        public AtlasEntity getById(String guid) {
+
+            if( entities != null) {
+                return entities.get(guid);
+            }
+
+            return null;
+        }
+
+        public Map<String, AtlasEntityWithAssociations> getEntities() {
+            return entities;
+        }
+
+        public void addEntities(Map<String, AtlasEntity> entities) {
+            if (this.entities == null) {
+                this.entities = new HashMap<>(entities.size());
+            }
+            for (String entityId : entities.keySet()) {
+                this.entities.put(entityId, new AtlasEntityWithAssociations(entities.get(entityId)));
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java
index 7368c72..692f917 100644
--- a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java
@@ -47,7 +47,11 @@ import org.apache.atlas.typesystem.exception.TypeNotFoundException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 @Singleton
 public class AtlasInstanceRestAdapters {
@@ -63,19 +67,24 @@ public class AtlasInstanceRestAdapters {
     @Inject
     private MetadataService metadataService;
 
-    public ITypedReferenceableInstance[] getITypedReferenceables(List<AtlasEntity> entities) throws AtlasBaseException {
+    public ITypedReferenceableInstance[] getITypedReferenceables(Collection<AtlasEntity> entities) throws AtlasBaseException {
         ITypedReferenceableInstance[] entitiesInOldFormat = new ITypedReferenceableInstance[entities.size()];
 
+        AtlasFormatConverter.ConverterContext ctx = new AtlasFormatConverter.ConverterContext();
+        for(Iterator<AtlasEntity> i = entities.iterator(); i.hasNext(); ) {
+            ctx.addEntity(i.next());
+        }
+
+        Iterator<AtlasEntity> entityIterator = entities.iterator();
         for (int i = 0; i < entities.size(); i++) {
-            ITypedReferenceableInstance typedInstance = getITypedReferenceable(entities.get(i));
+            ITypedReferenceableInstance typedInstance = getITypedReferenceable(entityIterator.next(), ctx);
             entitiesInOldFormat[i] = typedInstance;
         }
-
         return entitiesInOldFormat;
     }
 
-    public ITypedReferenceableInstance getITypedReferenceable(AtlasEntity entity) throws AtlasBaseException {
-        Referenceable ref = getReferenceable(entity);
+    public ITypedReferenceableInstance getITypedReferenceable(AtlasEntity entity, AtlasFormatConverter.ConverterContext ctx) throws AtlasBaseException {
+        Referenceable ref = getReferenceable(entity, ctx);
 
         try {
             return metadataService.getTypedReferenceableInstance(ref);
@@ -85,10 +94,10 @@ public class AtlasInstanceRestAdapters {
         }
     }
 
-    public Referenceable getReferenceable(AtlasEntity entity) throws AtlasBaseException {
+    public Referenceable getReferenceable(AtlasEntity entity, final AtlasFormatConverter.ConverterContext ctx) throws AtlasBaseException {
         AtlasFormatConverter converter  = instanceFormatters.getConverter(TypeCategory.ENTITY);
         AtlasType            entityType = typeRegistry.getType(entity.getTypeName());
-        Referenceable        ref        = (Referenceable)converter.fromV2ToV1(entity, entityType);
+        Referenceable        ref        = (Referenceable)converter.fromV2ToV1(entity, entityType, ctx);
 
         return ref;
     }
@@ -96,7 +105,7 @@ public class AtlasInstanceRestAdapters {
     public ITypedStruct getTrait(AtlasClassification classification) throws AtlasBaseException {
         AtlasFormatConverter converter          = instanceFormatters.getConverter(TypeCategory.CLASSIFICATION);
         AtlasType            classificationType = typeRegistry.getType(classification.getTypeName());
-        Struct               trait               = (Struct)converter.fromV2ToV1(classification, classificationType);
+        Struct               trait               = (Struct)converter.fromV2ToV1(classification, classificationType, new AtlasFormatConverter.ConverterContext());
 
         try {
             return metadataService.createTraitInstance(trait);
@@ -112,21 +121,22 @@ public class AtlasInstanceRestAdapters {
         if (classificationType == null) {
             throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.CLASSIFICATION.name(), classification.getTypeName());
         }
-        AtlasClassification  ret                = (AtlasClassification)converter.fromV1ToV2(classification, classificationType);
+        AtlasClassification  ret                = (AtlasClassification)converter.fromV1ToV2(classification, classificationType, new AtlasFormatConverter.ConverterContext());
 
         return ret;
     }
 
-    public AtlasEntityWithAssociations getAtlasEntity(IReferenceableInstance referenceable) throws AtlasBaseException {
+    public Map<String, AtlasEntityWithAssociations> getAtlasEntity(IReferenceableInstance referenceable) throws AtlasBaseException {
+
         AtlasFormatConverter converter  = instanceFormatters.getConverter(TypeCategory.ENTITY);
         AtlasEntityType entityType = typeRegistry.getEntityTypeByName(referenceable.getTypeName());
         if (entityType == null) {
             throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), referenceable.getTypeName());
         }
 
-        AtlasEntityWithAssociations ret = (AtlasEntityWithAssociations)converter.fromV1ToV2(referenceable, entityType);
-
-        return ret;
+        AtlasFormatConverter.ConverterContext ctx = new AtlasFormatConverter.ConverterContext();
+        converter.fromV1ToV2(referenceable, entityType, ctx);
+        return ctx.getEntities();
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasMapFormatConverter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasMapFormatConverter.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasMapFormatConverter.java
index f390e82..6967c4f 100644
--- a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasMapFormatConverter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasMapFormatConverter.java
@@ -35,7 +35,7 @@ public class AtlasMapFormatConverter extends AtlasAbstractFormatConverter {
     }
 
     @Override
-    public Map fromV1ToV2(Object v1Obj, AtlasType type) throws AtlasBaseException {
+    public Map fromV1ToV2(Object v1Obj, AtlasType type, ConverterContext ctx) throws AtlasBaseException {
         Map ret = null;
 
         if (v1Obj != null) {
@@ -52,8 +52,8 @@ public class AtlasMapFormatConverter extends AtlasAbstractFormatConverter {
                 for (Object key : v1Map.keySet()) {
                     Object value = v1Map.get(key);
 
-                    Object v2Key   = keyConverter.fromV1ToV2(key, keyType);
-                    Object v2Value = valueConverter.fromV1ToV2(value, valueType);
+                    Object v2Key   = keyConverter.fromV1ToV2(key, keyType, ctx);
+                    Object v2Value = valueConverter.fromV1ToV2(value, valueType, ctx);
 
                     ret.put(v2Key, v2Value);
                 }
@@ -67,7 +67,7 @@ public class AtlasMapFormatConverter extends AtlasAbstractFormatConverter {
     }
 
     @Override
-    public Map fromV2ToV1(Object v2Obj, AtlasType type) throws AtlasBaseException {
+    public Map fromV2ToV1(Object v2Obj, AtlasType type, ConverterContext ctx) throws AtlasBaseException {
         Map ret = null;
 
         if (v2Obj != null) {
@@ -84,8 +84,8 @@ public class AtlasMapFormatConverter extends AtlasAbstractFormatConverter {
                 for (Object key : v1Map.keySet()) {
                     Object value = v1Map.get(key);
 
-                    Object v2Key   = keyConverter.fromV2ToV1(key, keyType);
-                    Object v2Value = valueConverter.fromV2ToV1(value, valueType);
+                    Object v2Key   = keyConverter.fromV2ToV1(key, keyType, ctx);
+                    Object v2Value = valueConverter.fromV2ToV1(value, valueType, ctx);
 
                     ret.put(v2Key, v2Value);
                 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasObjectIdConverter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasObjectIdConverter.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasObjectIdConverter.java
new file mode 100644
index 0000000..b2de802
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasObjectIdConverter.java
@@ -0,0 +1,90 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.web.adapters;
+
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.TypeCategory;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.typesystem.IReferenceableInstance;
+import org.apache.atlas.typesystem.Referenceable;
+import org.apache.atlas.typesystem.persistence.Id;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Map;
+
+public class
+AtlasObjectIdConverter extends  AtlasAbstractFormatConverter {
+
+    public AtlasObjectIdConverter(AtlasFormatConverters registry, AtlasTypeRegistry typeRegistry) {
+        this(registry, typeRegistry, TypeCategory.OBJECT_ID_TYPE);
+    }
+
+    protected AtlasObjectIdConverter(AtlasFormatConverters registry, AtlasTypeRegistry typeRegistry, TypeCategory typeCategory) {
+        super(registry, typeRegistry, typeCategory);
+    }
+
+    @Override
+    public Object fromV1ToV2(Object v1Obj, AtlasType type, AtlasFormatConverter.ConverterContext converterContext) throws AtlasBaseException {
+        Object ret = null;
+
+        if (v1Obj != null) {
+            if (v1Obj instanceof Id) {
+                Id id = (Id) v1Obj;
+                ret = new AtlasObjectId(id.getTypeName(), id._getId());
+            } else if (v1Obj instanceof IReferenceableInstance) {
+                IReferenceableInstance entity = (IReferenceableInstance) v1Obj;
+                ret = new AtlasObjectId(entity.getTypeName(), entity.getId()._getId());
+            }
+        }
+        return ret;
+    }
+
+    @Override
+    public Object fromV2ToV1(Object v2Obj, AtlasType type, ConverterContext converterContext) throws AtlasBaseException {
+        Id ret = null;
+
+        if (v2Obj != null) {
+
+            if (v2Obj instanceof Map) {
+                Map    v2Map    = (Map) v2Obj;
+                String idStr    = (String)v2Map.get(AtlasObjectId.KEY_GUID);
+                String typeName = type.getTypeName();
+
+                if (StringUtils.isEmpty(idStr)) {
+                    throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND);
+                }
+
+                ret = new Id(idStr, 0, typeName);
+            } else if (v2Obj instanceof AtlasObjectId) { // transient-id
+                ret = new Id(((AtlasObjectId) v2Obj).getGuid(), 0, type.getTypeName());
+            } else if (v2Obj instanceof AtlasEntity) {
+                AtlasEntity entity = (AtlasEntity) v2Obj;
+                ret = new Id(((AtlasObjectId) v2Obj).getGuid(), 0, type.getTypeName());
+            } else {
+                throw new AtlasBaseException(AtlasErrorCode.TYPE_CATEGORY_INVALID, type.getTypeCategory().name());
+            }
+        }
+        return ret;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasPrimitiveFormatConverter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasPrimitiveFormatConverter.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasPrimitiveFormatConverter.java
index 382d1ef..2b70c5e 100644
--- a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasPrimitiveFormatConverter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasPrimitiveFormatConverter.java
@@ -30,12 +30,12 @@ public class AtlasPrimitiveFormatConverter extends AtlasAbstractFormatConverter
     }
 
     @Override
-    public Object fromV1ToV2(Object v1Obj, AtlasType type) throws AtlasBaseException {
+    public Object fromV1ToV2(Object v1Obj, AtlasType type, ConverterContext ctx) throws AtlasBaseException {
         return type.getNormalizedValue(v1Obj);
     }
 
     @Override
-    public Object fromV2ToV1(Object v2Obj, AtlasType type) throws AtlasBaseException {
+    public Object fromV2ToV1(Object v2Obj, AtlasType type, ConverterContext ctx) throws AtlasBaseException {
         return type.getNormalizedValue(v2Obj);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasStructFormatConverter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasStructFormatConverter.java b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasStructFormatConverter.java
index 4b3dd4c..4d2e123 100644
--- a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasStructFormatConverter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasStructFormatConverter.java
@@ -50,7 +50,7 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
     }
 
     @Override
-    public Object fromV1ToV2(Object v1Obj, AtlasType type) throws AtlasBaseException {
+    public Object fromV1ToV2(Object v1Obj, AtlasType type, ConverterContext converterContext) throws AtlasBaseException {
         AtlasStruct ret = null;
 
         if (v1Obj != null) {
@@ -61,7 +61,7 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
                 final Map v1Attribs = (Map) v1Map.get(ATTRIBUTES_PROPERTY_KEY);
 
                 if (MapUtils.isNotEmpty(v1Attribs)) {
-                    ret = new AtlasStruct(type.getTypeName(), fromV1ToV2(structType, v1Attribs));
+                    ret = new AtlasStruct(type.getTypeName(), fromV1ToV2(structType, v1Attribs, converterContext));
                 } else {
                     ret = new AtlasStruct(type.getTypeName());
                 }
@@ -75,7 +75,7 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
                     LOG.error("IStruct.getValuesMap() failed", excp);
                 }
 
-                ret = new AtlasStruct(type.getTypeName(), fromV1ToV2(structType, v1Attribs));
+                ret = new AtlasStruct(type.getTypeName(), fromV1ToV2(structType, v1Attribs, converterContext));
             } else {
                 throw new AtlasBaseException(AtlasErrorCode.UNEXPECTED_TYPE, "Map or IStruct", v1Obj.getClass().getCanonicalName());
             }
@@ -85,7 +85,7 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
     }
 
     @Override
-    public Object fromV2ToV1(Object v2Obj, AtlasType type) throws AtlasBaseException {
+    public Object fromV2ToV1(Object v2Obj, AtlasType type, ConverterContext converterContext) throws AtlasBaseException {
         Struct ret = null;
 
         if (v2Obj != null) {
@@ -102,14 +102,14 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
                 }
 
                 if (MapUtils.isNotEmpty(v2Attribs)) {
-                    ret = new Struct(type.getTypeName(), fromV2ToV1(structType, v2Attribs));
+                    ret = new Struct(type.getTypeName(), fromV2ToV1(structType, v2Attribs, converterContext));
                 } else {
                     ret = new Struct(type.getTypeName());
                 }
             } else if (v2Obj instanceof AtlasStruct) {
                 AtlasStruct struct = (AtlasStruct) v2Obj;
 
-                ret = new Struct(type.getTypeName(), fromV2ToV1(structType, struct.getAttributes()));
+                ret = new Struct(type.getTypeName(), fromV2ToV1(structType, struct.getAttributes(), converterContext));
             } else {
                 throw new AtlasBaseException(AtlasErrorCode.UNEXPECTED_TYPE, "Map or AtlasStruct", v2Obj.getClass().getCanonicalName());
             }
@@ -118,7 +118,7 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
         return ret;
     }
 
-    protected Map<String, Object> fromV2ToV1(AtlasStructType structType, Map attributes) throws AtlasBaseException {
+    protected Map<String, Object> fromV2ToV1(AtlasStructType structType, Map attributes, ConverterContext context) throws AtlasBaseException {
         Map<String, Object> ret = null;
 
         if (MapUtils.isNotEmpty(attributes)) {
@@ -132,11 +132,17 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
                     continue;
                 }
 
-                AtlasFormatConverter attrConverter = converterRegistry.getConverter(attrType.getTypeCategory());
-
                 Object v2Value = attributes.get(attr.getName());
-                Object v1Value = attrConverter.fromV2ToV1(v2Value, attrType);
+                Object v1Value = null;
 
+                AtlasFormatConverter attrConverter = null;
+                if (attrType.getTypeCategory() == TypeCategory.ENTITY && !attr.isContainedAttribute()) {
+                    attrConverter = new AtlasObjectIdConverter(converterRegistry, typeRegistry);
+                    v1Value = attrConverter.fromV2ToV1(v2Value, attrType, context);
+                } else {
+                    attrConverter = converterRegistry.getConverter(attrType.getTypeCategory());
+                    v1Value = attrConverter.fromV2ToV1(v2Value, attrType, context);
+                }
                 ret.put(attr.getName(), v1Value);
             }
         }
@@ -144,7 +150,7 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
         return ret;
     }
 
-    protected Map<String, Object> fromV1ToV2(AtlasStructType structType, Map attributes) throws AtlasBaseException {
+    protected Map<String, Object> fromV1ToV2(AtlasStructType structType, Map attributes, ConverterContext context) throws AtlasBaseException {
         Map<String, Object> ret = null;
 
         if (MapUtils.isNotEmpty(attributes)) {
@@ -152,11 +158,23 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
 
             for (AtlasStructType.AtlasAttribute attr : structType.getAllAttributes().values()) {
                 AtlasType            attrType      = attr.getAttributeType();
-                AtlasFormatConverter attrConverter = converterRegistry.getConverter(attrType.getTypeCategory());
+
+                if (attrType == null) {
+                    LOG.warn("ignored attribute {}.{}: failed to find AtlasType", structType.getTypeName(), attr.getName());
+                    continue;
+                }
 
                 Object v1Value = attributes.get(attr.getName());
-                Object v2Value = attrConverter.fromV1ToV2(v1Value, attrType);
+                Object v2Value = null;
 
+                AtlasFormatConverter attrConverter = null;
+                if (attrType.getTypeCategory() == TypeCategory.ENTITY && !attr.isContainedAttribute()) {
+                    attrConverter = new AtlasObjectIdConverter(converterRegistry, typeRegistry);
+                    v2Value = attrConverter.fromV1ToV2(v1Value, attrType, context);
+                } else {
+                    attrConverter = converterRegistry.getConverter(attrType.getTypeCategory());
+                    v2Value = attrConverter.fromV1ToV2(v1Value, attrType, context);
+                }
                 ret.put(attr.getAttributeDef().getName(), v2Value);
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java
index 5107767..af0377e 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java
@@ -25,6 +25,7 @@ import org.apache.atlas.model.SearchFilter;
 import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.AtlasEntityWithAssociations;
 import org.apache.atlas.model.instance.ClassificationAssociateRequest;
 import org.apache.atlas.model.instance.EntityMutationResponse;
 import org.apache.atlas.repository.store.graph.AtlasEntityStore;
@@ -53,6 +54,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -92,9 +94,10 @@ public class EntitiesREST {
     @POST
     @Consumes(Servlets.JSON_MEDIA_TYPE)
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public EntityMutationResponse createOrUpdate(List<AtlasEntity> entities) throws AtlasBaseException {
+    public EntityMutationResponse createOrUpdate(Map<String, AtlasEntity> entities) throws AtlasBaseException {
         EntityMutationResponse response = null;
-        ITypedReferenceableInstance[] entitiesInOldFormat = restAdapters.getITypedReferenceables(entities);
+
+        ITypedReferenceableInstance[] entitiesInOldFormat = restAdapters.getITypedReferenceables(entities.values());
 
         try {
             final AtlasClient.EntityResult result = metadataService.updateEntities(entitiesInOldFormat);
@@ -114,7 +117,7 @@ public class EntitiesREST {
     @PUT
     @Consumes(Servlets.JSON_MEDIA_TYPE)
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public EntityMutationResponse update(List<AtlasEntity> entities) throws AtlasBaseException {
+    public EntityMutationResponse update(Map<String, AtlasEntity> entities) throws AtlasBaseException {
        return createOrUpdate(entities);
     }
 
@@ -135,8 +138,10 @@ public class EntitiesREST {
         for (String guid : guids) {
             try {
                ITypedReferenceableInstance ref = metadataService.getEntityDefinition(guid);
-               AtlasEntity entity = restAdapters.getAtlasEntity(ref);
-               entityList.add(entity);
+               Map<String, AtlasEntityWithAssociations> entityRet = restAdapters.getAtlasEntity(ref);
+
+               addToEntityList(entityList, entityRet.values());
+
             } catch (AtlasException e) {
                 throw toAtlasBaseException(e);
             }
@@ -146,6 +151,14 @@ public class EntitiesREST {
         return entities;
     }
 
+    private void addToEntityList(final List<AtlasEntity> entityList, final Collection<AtlasEntityWithAssociations> values) {
+        for (AtlasEntityWithAssociations val : values) {
+            if ( !entityList.contains(val)) {
+                entityList.add(val);
+            }
+        }
+    }
+
     /*******
      * Entity Delete
      *******/
@@ -168,28 +181,6 @@ public class EntitiesREST {
     }
 
     /**
-     * Bulk retrieval API for searching on entities by certain predefined attributes ( typeName, superType, name, qualifiedName etc) + optional user defined attributes
-     *
-     * @throws AtlasBaseException
-     */
-    @GET
-    @Produces(Servlets.JSON_MEDIA_TYPE)
-    public AtlasEntityHeader.AtlasEntityHeaders searchEntities() throws AtlasBaseException {
-        SearchFilter searchFilter = getSearchFilter();
-        AtlasEntity.AtlasEntities atlasEntities = entitiesStore.searchEntities(searchFilter);
-        AtlasEntityHeader.AtlasEntityHeaders entityHeaders = new AtlasEntityHeader.AtlasEntityHeaders();
-        entityHeaders.setList(new LinkedList<AtlasEntityHeader>());
-
-        if (atlasEntities != null) {
-            for (AtlasEntity atlasEntity : atlasEntities.getList()) {
-                entityHeaders.getList().add(new AtlasEntityHeader(atlasEntity.getTypeName(), atlasEntity.getAttributes()));
-            }
-        }
-
-        return entityHeaders;
-    }
-
-    /**
      * Bulk API to associate a tag to multiple entities
      *
      */
@@ -219,15 +210,4 @@ public class EntitiesREST {
             throw toAtlasBaseException(e);
         }
     }
-
-    private SearchFilter getSearchFilter() {
-        SearchFilter searchFilter = new SearchFilter();
-        if (null != httpServletRequest && null != httpServletRequest.getParameterMap()) {
-            for (Map.Entry<String, String[]> entry : httpServletRequest.getParameterMap().entrySet()) {
-                searchFilter.setParam(entry.getKey(), Arrays.asList(entry.getValue()));
-            }
-        }
-        return searchFilter;
-    }
-
 }