[OLINGO-545] Fix: Bind operations are applyed before creating deep insert entities
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/189de7b2 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/189de7b2 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/189de7b2 Branch: refs/heads/OLINGO-573 Commit: 189de7b2d70f84260d76ed323e22d85bf9cd6d57 Parents: 502f7ce Author: Christian Holzer <[email protected]> Authored: Thu Apr 2 15:04:00 2015 +0200 Committer: Christian Holzer <[email protected]> Committed: Fri Apr 3 12:42:00 2015 +0200 ---------------------------------------------------------------------- .../olingo/fit/tecsvc/client/BindingITCase.java | 47 ++++++++++++++++++++ .../olingo/server/tecsvc/data/DataProvider.java | 15 ++++--- 2 files changed, 56 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/189de7b2/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java index d0435b2..75cadd0 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java @@ -25,6 +25,7 @@ import java.net.URI; import java.util.HashMap; import java.util.Iterator; +import org.apache.olingo.client.api.EdmEnabledODataClient; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.request.cud.UpdateType; @@ -34,6 +35,7 @@ import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResp import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.core.ODataClientFactory; import org.apache.olingo.commons.api.domain.ODataEntity; +import org.apache.olingo.commons.api.domain.ODataInlineEntity; import org.apache.olingo.commons.api.domain.ODataLink; import org.apache.olingo.commons.api.domain.ODataObjectFactory; import org.apache.olingo.commons.api.domain.ODataProperty; @@ -310,6 +312,51 @@ public class BindingITCase extends AbstractBaseTestITCase { } } + @Test + public void testDeepInsertWithBindingSameNavigationProperty() { + final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); + client.getConfiguration().setDefaultPubFormat(ODataFormat.JSON); + final ODataObjectFactory of = client.getObjectFactory(); + + final ODataEntity entity = of.newEntity(ET_KEY_NAV); + entity.getProperties().add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder() + .buildString("1"))); + entity.getProperties().add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short)1))) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("1"))))); + + final ODataEntity innerEntity = of.newEntity(ET_KEY_NAV); + innerEntity.getProperties().add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder() + .buildString("2"))); + innerEntity.getProperties().add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 1))) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("2"))))); + + final ODataInlineEntity inlineLink = of.newDeepInsertEntity(NAV_PROPERTY_ET_KEY_NAV_ONE, innerEntity); + entity.addLink(inlineLink); + + final URI bindingURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV) + .appendKeySegment(3) + .build(); + + entity.addLink(of.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, bindingURI)); + + final URI targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build(); + final ODataEntityCreateResponse<ODataEntity> response = + client.getCUDRequestFactory().getEntityCreateRequest(targetURI, entity).execute(); + + assertEquals(HttpStatusCode.CREATED.getStatusCode(), response.getStatusCode()); + + assertEquals(1, response.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE) + .asInlineEntity() + .getEntity() + .getProperty(PROPERTY_COMP_TWO_PRIM) + .getComplexValue() + .get(PROPERTY_INT16) + .getPrimitiveValue() + .toValue()); + } + @Override protected ODataClient getClient() { ODataClient odata = ODataClientFactory.getClient(); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/189de7b2/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java index e4bb0a2..96f0cd7 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java @@ -243,18 +243,21 @@ public class DataProvider { patch); } } - + + // For insert operations collection navigation property bind operations and deep insert operations can be combined. + // In this case, the bind operations MUST appear before the deep insert operations in the payload. + // => Apply bindings first + final boolean navigationBindingsAvailable = !changedEntity.getNavigationBindings().isEmpty(); + if (navigationBindingsAvailable) { + applyNavigationBinding(rawBaseUri, edmEntitySet, entity, changedEntity.getNavigationBindings()); + } + // Deep insert (only if not an update) if (isInsert) { handleDeepInsert(rawBaseUri, edmEntitySet, entity, changedEntity); } else { handleDeleteSingleNavigationProperties(edmEntitySet, entity, changedEntity); } - - final boolean navigationBindingsAvailable = !changedEntity.getNavigationBindings().isEmpty(); - if (navigationBindingsAvailable) { - applyNavigationBinding(rawBaseUri, edmEntitySet, entity, changedEntity.getNavigationBindings()); - } } private void handleDeleteSingleNavigationProperties(EdmEntitySet edmEntitySet, Entity entity, Entity changedEntity)
