You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/03/19 16:02:03 UTC

[1/2] olingo-odata4 git commit: [OLINGO-596] Fix: The client URIBuilder uses semicolons instead of commas to split system query options in expand options

Repository: olingo-odata4
Updated Branches:
  refs/heads/master a42641f70 -> 4f15c7c72


[OLINGO-596] Fix: The client URIBuilder uses semicolons instead of commas
to split system query options in expand options


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/b9827515
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/b9827515
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/b9827515

Branch: refs/heads/master
Commit: b98275153a9895d1ca69fd0fd76c236037f6e444
Parents: a42641f
Author: Christian Holzer <c....@sap.com>
Authored: Wed Mar 18 17:00:29 2015 +0100
Committer: Christian Holzer <c....@sap.com>
Committed: Thu Mar 19 15:55:01 2015 +0100

----------------------------------------------------------------------
 .../olingo/client/core/uri/URIBuilderImpl.java  |  9 ++-
 .../client/core/uri/v4/URIBuilderTest.java      | 83 ++++++++++----------
 2 files changed, 47 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9827515/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java
index 2815a61..452596c 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/URIBuilderImpl.java
@@ -143,7 +143,7 @@ public class URIBuilderImpl implements URIBuilder {
   @Override
   public URIBuilder appendKeySegment(final Map<String, Object> segmentValues) {
     if (!configuration.isKeyAsSegment()) {
-      final String key = buildMultiKeySegment(segmentValues, true);
+      final String key = buildMultiKeySegment(segmentValues, true, ',');
       if (StringUtils.isEmpty(key)) {
         segments.add(new Segment(SegmentType.KEY, noKeysWrapper()));
       } else {
@@ -330,7 +330,8 @@ public class URIBuilderImpl implements URIBuilder {
     return build().toASCIIString();
   }
 
-  protected String buildMultiKeySegment(final Map<String, Object> segmentValues, final boolean escape) {
+  protected String buildMultiKeySegment(final Map<String, Object> segmentValues, final boolean escape,
+      final char sperator) {
     if (segmentValues == null || segmentValues.isEmpty()) {
       return StringUtils.EMPTY;
     } else {
@@ -338,7 +339,7 @@ public class URIBuilderImpl implements URIBuilder {
       for (Map.Entry<String, Object> entry : segmentValues.entrySet()) {
         keyBuilder.append(entry.getKey()).append('=').append(
             escape ? URIUtils.escape(entry.getValue()) : entry.getValue());
-        keyBuilder.append(',');
+        keyBuilder.append(sperator);
       }
       keyBuilder.deleteCharAt(keyBuilder.length() - 1).append(')');
 
@@ -434,7 +435,7 @@ public class URIBuilderImpl implements URIBuilder {
     for (Map.Entry<QueryOption, Object> entry : options.entrySet()) {
       _options.put("$" + entry.getKey().toString(), entry.getValue());
     }
-    return expand(expandItem + buildMultiKeySegment(_options, false));
+    return expand(expandItem + buildMultiKeySegment(_options, false, ';'));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9827515/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/v4/URIBuilderTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/v4/URIBuilderTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/v4/URIBuilderTest.java
index 731bf1d..15465dc 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/v4/URIBuilderTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/v4/URIBuilderTest.java
@@ -1,18 +1,18 @@
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
+ * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
+ * 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
- *
+ * 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
+ * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
@@ -27,7 +27,9 @@ import org.junit.Test;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
 
@@ -43,27 +45,26 @@ public class URIBuilderTest extends AbstractTest {
   @Test
   public void expandWithOptions() throws URISyntaxException {
     final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
-            expandWithOptions("ProductDetails", new LinkedHashMap<QueryOption, Object>() {
-              private static final long serialVersionUID = 3109256773218160485L;
+        expandWithOptions("ProductDetails", new LinkedHashMap<QueryOption, Object>() {
+          private static final long serialVersionUID = 3109256773218160485L;
 
-              {
-                put(QueryOption.EXPAND, "ProductInfo");
-                put(QueryOption.SELECT, "Price");
-              }
-            }).expand("Orders", "Customers").build();
+          {
+            put(QueryOption.EXPAND, "ProductInfo");
+            put(QueryOption.SELECT, "Price");
+          }
+        }).expand("Orders", "Customers").build();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products(5)").
-            addParameter("$expand", "ProductDetails($expand=ProductInfo,$select=Price),Orders,Customers").build(), uri);
+        addParameter("$expand", "ProductDetails($expand=ProductInfo;$select=Price),Orders,Customers").build(), uri);
   }
 
-  @Test
   public void expandWithLevels() throws URISyntaxException {
     final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(1).
-            expandWithOptions("Customer", Collections.<QueryOption, Object>singletonMap(QueryOption.LEVELS, 4)).
-            build();
+        expandWithOptions("Customer", Collections.<QueryOption, Object> singletonMap(QueryOption.LEVELS, 4)).
+        build();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products(1)").
-            addParameter("$expand", "Customer($levels=4)").build(), uri);
+        addParameter("$expand", "Customer($levels=4)").build(), uri);
   }
 
   @Test
@@ -75,72 +76,72 @@ public class URIBuilderTest extends AbstractTest {
     uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count(true).build();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products").
-            addParameter("$count", "true").build(), uri);
+        addParameter("$count", "true").build(), uri);
   }
 
   @Test
   public void singleton() throws URISyntaxException {
     final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
-            appendSingletonSegment("BestProductEverCreated");
+        appendSingletonSegment("BestProductEverCreated");
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
-            SERVICE_ROOT + "/BestProductEverCreated").build(), uriBuilder.build());
+        SERVICE_ROOT + "/BestProductEverCreated").build(), uriBuilder.build());
   }
 
   @Test
   public void entityId() throws URISyntaxException {
     final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
-            appendEntityIdSegment("Products(0)");
+        appendEntityIdSegment("Products(0)");
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
-            SERVICE_ROOT + "/$entity").addParameter("$id", "Products(0)").build(), uriBuilder.build());
+        SERVICE_ROOT + "/$entity").addParameter("$id", "Products(0)").build(), uriBuilder.build());
   }
 
   @Test
   public void boundAction() throws URISyntaxException {
     final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
-            appendEntitySetSegment("Categories").appendKeySegment(1).
-            appendNavigationSegment("Products").appendNavigationSegment("Model").
-            appendOperationCallSegment("AllOrders");
+        appendEntitySetSegment("Categories").appendKeySegment(1).
+        appendNavigationSegment("Products").appendNavigationSegment("Model").
+        appendOperationCallSegment("AllOrders");
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
-            SERVICE_ROOT + "/Categories(1)/Products/Model.AllOrders()").build(), uriBuilder.build());
+        SERVICE_ROOT + "/Categories(1)/Products/Model.AllOrders()").build(), uriBuilder.build());
   }
 
   @Test
   public void ref() throws URISyntaxException {
     URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
-            appendEntitySetSegment("Categories").appendKeySegment(1).
-            appendNavigationSegment("Products").appendRefSegment();
+        appendEntitySetSegment("Categories").appendKeySegment(1).
+        appendNavigationSegment("Products").appendRefSegment();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
-            SERVICE_ROOT + "/Categories(1)/Products/$ref").build(), uriBuilder.build());
+        SERVICE_ROOT + "/Categories(1)/Products/$ref").build(), uriBuilder.build());
 
     uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
-            appendEntitySetSegment("Categories").appendKeySegment(1).
-            appendNavigationSegment("Products").appendRefSegment().id("../../Products(0)");
+        appendEntitySetSegment("Categories").appendKeySegment(1).
+        appendNavigationSegment("Products").appendRefSegment().id("../../Products(0)");
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
-            SERVICE_ROOT + "/Categories(1)/Products/$ref").addParameter("$id", "../../Products(0)").build(),
-            uriBuilder.build());
+        SERVICE_ROOT + "/Categories(1)/Products/$ref").addParameter("$id", "../../Products(0)").build(),
+        uriBuilder.build());
   }
 
   @Test
   public void derived() throws URISyntaxException {
     final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
-            appendEntitySetSegment("Customers").appendDerivedEntityTypeSegment("Model.VipCustomer").appendKeySegment(1);
+        appendEntitySetSegment("Customers").appendDerivedEntityTypeSegment("Model.VipCustomer").appendKeySegment(1);
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
-            SERVICE_ROOT + "/Customers/Model.VipCustomer(1)").build(), uriBuilder.build());
+        SERVICE_ROOT + "/Customers/Model.VipCustomer(1)").build(), uriBuilder.build());
   }
 
   @Test
   public void crossjoin() throws URISyntaxException {
     final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
-            appendCrossjoinSegment("Products", "Sales");
+        appendCrossjoinSegment("Products", "Sales");
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
-            SERVICE_ROOT + "/$crossjoin(Products,Sales)").build(), uriBuilder.build());
+        SERVICE_ROOT + "/$crossjoin(Products,Sales)").build(), uriBuilder.build());
   }
 
   @Test
@@ -148,13 +149,13 @@ public class URIBuilderTest extends AbstractTest {
     final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).appendAllSegment();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
-            SERVICE_ROOT + "/$all").build(), uriBuilder.build());
+        SERVICE_ROOT + "/$all").build(), uriBuilder.build());
   }
 
   @Test
   public void search() throws URISyntaxException {
     final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
-            appendEntitySetSegment("Products").search("blue OR green");
+        appendEntitySetSegment("Products").search("blue OR green");
 
     assertEquals(new URI("http://host/service/Products?%24search=blue%20OR%20green"), uriBuilder.build());
   }


[2/2] olingo-odata4 git commit: [OLINGO-545] Expand supports the system query options $top, $skip, $filter, $orderby, $select

Posted by ch...@apache.org.
[OLINGO-545] Expand supports the system query options $top, $skip, $filter, $orderby, $select


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/4f15c7c7
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/4f15c7c7
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/4f15c7c7

Branch: refs/heads/master
Commit: 4f15c7c7246c99a8a59f1334ed2b8fdecfe0eb55
Parents: b982751
Author: Christian Holzer <c....@sap.com>
Authored: Thu Mar 12 16:51:45 2015 +0100
Committer: Christian Holzer <c....@sap.com>
Committed: Thu Mar 19 15:56:08 2015 +0100

----------------------------------------------------------------------
 .../ExpandWithSystemQueryOptionsITCase.java     | 260 +++++++++++++++++++
 .../olingo/server/tecsvc/data/DataCreator.java  |   6 +-
 .../processor/TechnicalEntityProcessor.java     |  14 +-
 .../ExpandSystemQueryOptionHandler.java         | 152 +++++++++++
 .../tecsvc/provider/ComplexTypeProvider.java    |   4 +-
 .../tecsvc/provider/EntityTypeProvider.java     |   2 +-
 .../tecsvc/provider/PropertyProvider.java       |  16 +-
 7 files changed, 441 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f15c7c7/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
new file mode 100644
index 0000000..a6b6eb9
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
@@ -0,0 +1,260 @@
+/*
+ * 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.olingo.fit.tecsvc.client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.client.api.EdmEnabledODataClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.uri.QueryOption;
+import org.apache.olingo.client.core.ODataClientFactory;
+import org.apache.olingo.commons.api.domain.ODataEntity;
+import org.apache.olingo.commons.api.domain.ODataEntitySet;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.fit.AbstractBaseTestITCase;
+import org.apache.olingo.fit.tecsvc.TecSvcConst;
+import org.junit.Test;
+
+public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
+
+  private static final String ES_KEY_NAV = "ESKeyNav";
+  private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
+  private static final String NAV_PROPERTY_ET_KEY_NAV_MANY = "NavPropertyETKeyNavMany";
+  private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
+  private static final String SERVICE_URI = TecSvcConst.BASE_URI;
+  private static final String PROPERTY_INT16 = "PropertyInt16";
+  private static final String PROPERTY_STRING = "PropertyString";
+
+  @Test
+  public void testFilter() {
+    final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    options.put(QueryOption.FILTER, "PropertyString eq '2'");
+
+    final ODataRetrieveResponse<ODataEntitySet> response =
+        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+    final List<ODataEntity> entities = response.getBody().getEntities();
+    assertEquals(4, entities.size());
+
+    for (final ODataEntity entity : entities) {
+      final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
+      final Object propString = entity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
+      final ODataEntitySet inlineEntitySet =
+          entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
+
+      if (propInt16.equals(1) && propString.equals("1")) {
+        assertEquals(1, inlineEntitySet.getEntities().size());
+        final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
+
+        assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+        assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+      } else if (propInt16.equals(1) && propString.equals("2")) {
+        assertEquals(0, inlineEntitySet.getEntities().size());
+      } else if (propInt16.equals(2) && propString.equals("1")) {
+        assertEquals(1, inlineEntitySet.getEntities().size());
+        final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
+
+        assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+        assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+      } else if (propInt16.equals(3) && propString.equals("1")) {
+        assertEquals(0, inlineEntitySet.getEntities().size());
+      } else {
+        fail();
+      }
+    }
+  }
+
+  @Test
+  public void testOrderBy() {
+    final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    options.put(QueryOption.ORDERBY, "PropertyString desc");
+
+    final ODataRetrieveResponse<ODataEntitySet> response =
+        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+    final List<ODataEntity> entities = response.getBody().getEntities();
+    assertEquals(4, entities.size());
+
+    for (final ODataEntity entity : entities) {
+      final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
+      final Object propString = entity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
+      final ODataEntitySet inlineEntitySet =
+          entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
+
+      if (propInt16.equals(1) && propString.equals("1")) {
+        assertEquals(2, inlineEntitySet.getEntities().size());
+        final ODataEntity inlineEntity1 = inlineEntitySet.getEntities().get(0);
+        final ODataEntity inlineEntity2 = inlineEntitySet.getEntities().get(1);
+
+        assertEquals(1, inlineEntity1.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+        assertEquals("2", inlineEntity1.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+
+        assertEquals(1, inlineEntity2.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+        assertEquals("1", inlineEntity2.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+      }
+    }
+  }
+
+  @Test
+  public void testSkip() {
+    final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    options.put(QueryOption.SKIP, "1");
+
+    final ODataRetrieveResponse<ODataEntitySet> response =
+        buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY, options);
+    final List<ODataEntity> entities = response.getBody().getEntities();
+    assertEquals(3, entities.size());
+
+    for (final ODataEntity entity : entities) {
+      final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
+      final ODataEntitySet inlineEntitySet =
+          entity.getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
+
+      if (propInt16.equals(1)) {
+        assertEquals(1, inlineEntitySet.getEntities().size());
+        final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
+
+        assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+      } else if (propInt16.equals(2)) {
+        assertEquals(1, inlineEntitySet.getEntities().size());
+        final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
+
+        assertEquals(3, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+      } else if (propInt16.equals(3)) {
+        assertEquals(0, inlineEntitySet.getEntities().size());
+      }
+    }
+  }
+
+  @Test
+  public void testTop() {
+    final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    options.put(QueryOption.TOP, "1");
+
+    final ODataRetrieveResponse<ODataEntitySet> response =
+        buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY, options);
+    final List<ODataEntity> entities = response.getBody().getEntities();
+    assertEquals(3, entities.size());
+
+    for (final ODataEntity entity : entities) {
+      final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
+      final ODataEntitySet inlineEntitySet =
+          entity.getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
+
+      if (propInt16.equals(1)) {
+        assertEquals(1, inlineEntitySet.getEntities().size());
+        final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
+
+        assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+      } else if (propInt16.equals(2)) {
+        assertEquals(1, inlineEntitySet.getEntities().size());
+        final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
+
+        assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+      } else if (propInt16.equals(3)) {
+        assertEquals(0, inlineEntitySet.getEntities().size());
+      }
+    }
+  }
+
+  @Test
+  public void testCombinedSystemQueryOptions() {
+    final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    options.put(QueryOption.SELECT, "PropertyInt16,PropertyString");
+    options.put(QueryOption.FILTER, "PropertyInt16 eq 1");
+    options.put(QueryOption.SKIP, "1");
+
+    final ODataRetrieveResponse<ODataEntitySet> response =
+        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+    final List<ODataEntity> entities = response.getBody().getEntities();
+    assertEquals(4, entities.size());
+
+    for (final ODataEntity entity : entities) {
+      final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
+      final Object propString = entity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
+      final ODataEntitySet inlineEntitySet =
+          entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
+
+      if (propInt16.equals(1) && propString.equals("1")) {
+        assertEquals(1, inlineEntitySet.getEntities().size());
+        final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
+
+        assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+        assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+      } else if (propInt16.equals(1) && propString.equals("2")) {
+        assertEquals(0, inlineEntitySet.getEntities().size());
+      } else if (propInt16.equals(2) && propString.equals("1")) {
+        assertEquals(0, inlineEntitySet.getEntities().size());
+      } else if (propInt16.equals(3) && propString.equals("1")) {
+        assertEquals(0, inlineEntitySet.getEntities().size());
+      } else {
+        fail();
+      }
+    }
+  }
+  
+  @Test
+  public void testURIEscaping() {
+    final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    options.put(QueryOption.FILTER, "PropertyInt16 eq 1" 
+    + " and PropertyComp/PropertyComp/PropertyDuration eq duration'PT1S' and length(PropertyString) gt 4");
+    final ODataRetrieveResponse<ODataEntitySet> response =
+        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+    final List<ODataEntity> entities = response.getBody().getEntities();
+    
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
+    assertEquals(4, entities.size());
+  }
+  
+  private ODataRetrieveResponse<ODataEntitySet> buildRequest(final String entitySet, final String navigationProperty,
+      final Map<QueryOption, Object> expandOptions) {
+    return buildRequest(entitySet, navigationProperty, expandOptions, null);
+  }
+
+  private ODataRetrieveResponse<ODataEntitySet> buildRequest(final String entitySet, final String navigationProperty,
+      final Map<QueryOption, Object> expandOptions, final String cookie) {
+    final ODataClient client = getClient();
+    final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(entitySet)
+        .expandWithOptions(navigationProperty, expandOptions)
+        .build();
+
+    final ODataEntitySetRequest<ODataEntitySet> request = client.getRetrieveRequestFactory().getEntitySetRequest(uri);
+
+    if (cookie != null) {
+      request.addCustomHeader(HttpHeader.COOKIE, cookie);
+    }
+
+    return request.execute();
+  }
+
+  @Override
+  protected ODataClient getClient() {
+    EdmEnabledODataClient odata = ODataClientFactory.getEdmEnabledClient(SERVICE_URI);
+    odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
+    return odata;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f15c7c7/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
index 1e4a707..28781a3 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
@@ -664,9 +664,9 @@ public class DataCreator {
 
     // NavPropertyETTwoKeyNavMany
     setLinks(entitySet.getEntities().get(0), "NavPropertyETTwoKeyNavMany",
-        esKeyNavTargets.get(0), esKeyNavTargets.get(1));
-    setLinks(entitySet.getEntities().get(1), "NavPropertyETTwoKeyNavMany", esKeyNavTargets.get(0));
-    setLinks(entitySet.getEntities().get(2), "NavPropertyETTwoKeyNavMany", esKeyNavTargets.get(1));
+        esTwoKeyNavTargets.get(0), esTwoKeyNavTargets.get(1));
+    setLinks(entitySet.getEntities().get(1), "NavPropertyETTwoKeyNavMany", esTwoKeyNavTargets.get(0));
+    setLinks(entitySet.getEntities().get(2), "NavPropertyETTwoKeyNavMany", esTwoKeyNavTargets.get(1));
   }
 
   protected static Property createPrimitive(final String name, final Object value) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f15c7c7/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index 3021db3..b66482a 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -55,6 +55,7 @@ import org.apache.olingo.server.api.uri.UriResourceFunction;
 import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
 import org.apache.olingo.server.api.uri.queryoption.SelectOption;
 import org.apache.olingo.server.tecsvc.data.DataProvider;
+import org.apache.olingo.server.tecsvc.processor.queryoptions.ExpandSystemQueryOptionHandler;
 import org.apache.olingo.server.tecsvc.processor.queryoptions.options.CountHandler;
 import org.apache.olingo.server.tecsvc.processor.queryoptions.options.FilterHandler;
 import org.apache.olingo.server.tecsvc.processor.queryoptions.options.OrderByHandler;
@@ -104,12 +105,21 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
           entitySet,
           edmEntitySet,
           request.getRawRequestUri());
-
+      
+      // Apply expand system query option
       final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
       ODataSerializer serializer = odata.createSerializer(format);
       final ExpandOption expand = uriInfo.getExpandOption();
       final SelectOption select = uriInfo.getSelectOption();
-      response.setContent(serializer.entityCollection(edmEntityType, entitySet,
+      
+      // Create a shallow copy of each entity. So the expanded navigation properties can be modified for serialization,
+      // without affecting the data stored in the database.
+      final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
+      final EntitySet entitySetSerialization = expandHandler.copyEntitySetShallowRekursive(entitySet);
+      expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand);
+      
+      // Serialize
+      response.setContent(serializer.entityCollection(edmEntityType, entitySetSerialization,
           EntityCollectionSerializerOptions.with()
               .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
                   getContextUrl(edmEntitySet, edmEntityType, false, expand, select))

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f15c7c7/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
new file mode 100644
index 0000000..61fe162
--- /dev/null
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
@@ -0,0 +1,152 @@
+/*
+ * 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.olingo.server.tecsvc.processor.queryoptions;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntitySet;
+import org.apache.olingo.commons.api.data.Link;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.commons.core.data.EntityImpl;
+import org.apache.olingo.commons.core.data.EntitySetImpl;
+import org.apache.olingo.commons.core.data.LinkImpl;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceNavigation;
+import org.apache.olingo.server.api.uri.queryoption.CountOption;
+import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.FilterOption;
+import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
+import org.apache.olingo.server.api.uri.queryoption.SkipOption;
+import org.apache.olingo.server.api.uri.queryoption.TopOption;
+import org.apache.olingo.server.tecsvc.processor.queryoptions.options.FilterHandler;
+import org.apache.olingo.server.tecsvc.processor.queryoptions.options.OrderByHandler;
+import org.apache.olingo.server.tecsvc.processor.queryoptions.options.SkipHandler;
+import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler;
+
+public class ExpandSystemQueryOptionHandler {
+  private HashMap<Entity, Entity> copiedEntities = new HashMap<Entity, Entity>();
+  private HashMap<EntitySet, EntitySet> copiedEntitySets = new HashMap<EntitySet, EntitySet>();
+
+  public void applyExpandQueryOptions(final EntitySet entitySet, final EdmEntitySet edmEntitySet,
+      final ExpandOption expandOption) throws ODataApplicationException {
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
+    if (expandOption == null) {
+      return;
+    }
+
+    for (ExpandItem item : expandOption.getExpandItems()) {
+      final List<UriResource> uriResourceParts = item.getResourcePath().getUriResourceParts();
+      if (uriResourceParts.size() == 1 && uriResourceParts.get(0) instanceof UriResourceNavigation) {
+        final String navPropertyName = ((UriResourceNavigation) uriResourceParts.get(0)).getProperty().getName();
+        final EdmEntitySet targetEdmEntitySet = (EdmEntitySet) edmEntitySet.getRelatedBindingTarget(navPropertyName);
+
+        for (final Entity entity : entitySet.getEntities()) {
+          final Link link = entity.getNavigationLink(navPropertyName);
+          if (link != null && entityType.getNavigationProperty(navPropertyName).isCollection()) {
+            applyOptionsToEntityCollection(link.getInlineEntitySet(), targetEdmEntitySet, item.getFilterOption(),
+                item.getOrderByOption(), item.getCountOption(), item.getSkipOption(), item.getTopOption());
+          }
+        }
+      } else {
+        throw new ODataApplicationException("Not supported resource part in expand system query option",
+            HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+      }
+    }
+  }
+
+  private void applyOptionsToEntityCollection(final EntitySet entitySet, final EdmEntitySet edmEntitySet,
+      final FilterOption filterOption, final OrderByOption orderByOption, final CountOption countOption,
+      final SkipOption skipOption, final TopOption topOption) throws ODataApplicationException {
+
+    FilterHandler.applyFilterSystemQuery(filterOption, entitySet, edmEntitySet);
+    OrderByHandler.applyOrderByOption(orderByOption, entitySet, edmEntitySet);
+    SkipHandler.applySkipSystemQueryHandler(skipOption, entitySet);
+    TopHandler.applyTopSystemQueryOption(topOption, entitySet);
+  }
+
+  public EntitySet copyEntitySetShallowRekursive(final EntitySet entitySet) {
+    if (!copiedEntitySets.containsKey(entitySet)) {
+      final EntitySet copiedEntitySet = new EntitySetImpl();
+      copiedEntitySet.setCount(entitySet.getCount());
+      copiedEntitySet.setDeltaLink(entitySet.getDeltaLink());
+      copiedEntitySet.setNext(entitySet.getNext());
+
+      copiedEntitySets.put(entitySet, copiedEntitySet);
+      copiedEntitySets.put(copiedEntitySet, copiedEntitySet);
+      
+      for (Entity entity : entitySet.getEntities()) {
+        copiedEntitySet.getEntities().add(copyEntityShallowRekursive(entity));
+      }
+      return copiedEntitySet;
+    }
+    return copiedEntitySets.get(entitySet);
+  }
+
+  private Entity copyEntityShallowRekursive(final Entity entity) {
+    if (!copiedEntities.containsKey(entity)) {
+      final Entity copiedEntity = new EntityImpl();
+      copiedEntity.getProperties().addAll(entity.getProperties());
+      copiedEntity.getAnnotations().addAll(entity.getAnnotations());
+      copiedEntity.getAssociationLinks().addAll(entity.getAssociationLinks());
+      copiedEntity.setEditLink(entity.getEditLink());
+      copiedEntity.setId(entity.getId());
+      copiedEntity.setMediaContentSource(entity.getMediaContentSource());
+      copiedEntity.setMediaContentType(entity.getMediaContentType());
+      copiedEntity.setMediaETag(entity.getMediaETag());
+      copiedEntity.getOperations().addAll(entity.getOperations());
+      copiedEntity.setSelfLink(entity.getSelfLink());
+      copiedEntity.setType(entity.getType());
+      copiedEntity.getNavigationBindings().addAll(entity.getNavigationBindings());
+      
+      copiedEntities.put(entity, copiedEntity);
+      copiedEntities.put(copiedEntity, copiedEntity);
+
+      // The system query options change the amount and sequence of inline entities (feeds)
+      // So we have to make a shallow copy of all navigation link lists
+      // Make sure, that each entity is only copied once.
+      // Otherwise an infinite loop can occur caused by cyclic navigation relationships.
+
+      for (final Link link : entity.getNavigationLinks()) {
+        final Link newLink = new LinkImpl();
+        newLink.setMediaETag(link.getMediaETag());
+        newLink.setTitle(link.getTitle());
+        newLink.setType(link.getType());
+        newLink.setRel(link.getRel());
+
+        final EntitySet inlineEntitySet = link.getInlineEntitySet();
+        if (inlineEntitySet != null) {
+          newLink.setInlineEntitySet(copyEntitySetShallowRekursive(inlineEntitySet));
+        } else if (link.getInlineEntity() != null) {
+          newLink.setInlineEntity(copyEntityShallowRekursive(link.getInlineEntity()));
+        }
+        copiedEntity.getNavigationLinks().add(newLink);
+      }
+
+      return copiedEntity;
+    }
+    return copiedEntities.get(entity);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f15c7c7/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
index 767d639..ad0f182 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
@@ -140,7 +140,7 @@ public class ComplexTypeProvider {
           .setProperties(Arrays.asList(PropertyProvider.propertyInt16))
           .setNavigationProperties((Arrays.asList(
               PropertyProvider.collectionNavPropertyETTwoKeyNavOne_ETTwoKeyNav,
-              PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav,
+              PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav_WithPartnerERKeyNavOne,
               new NavigationProperty()
                   .setName("NavPropertyETMediaOne")
                   .setType(EntityTypeProvider.nameETMedia),
@@ -154,7 +154,7 @@ public class ComplexTypeProvider {
           .setName("CTBasePrimCompNav")
           .setBaseType(nameCTPrimComp)
           .setNavigationProperties(Arrays.asList(
-              PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav,
+              PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav_WithPartnerERKeyNavOne,
               PropertyProvider.collectionNavPropertyETTwoKeyNavOne_ETTwoKeyNav,
               PropertyProvider.navPropertyETKeyNavOne_ETKeyNav,
               PropertyProvider.collectionNavPropertyETKeyNavMany_ETKeyNav));

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f15c7c7/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
index 8004b17..cfcbcdc 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
@@ -315,7 +315,7 @@ public class EntityTypeProvider {
           .setNavigationProperties(
               Arrays.asList(
                   PropertyProvider.navPropertyETTwoKeyNavOne_ETTwoKeyNav_NotNullable,
-                  PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav,
+                  PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav_WithPartnerERKeyNavOne,
                   PropertyProvider.navPropertyETKeyNavOne_ETKeyNav,
                   PropertyProvider.collectionNavPropertyETKeyNavMany_ETKeyNav,
                   PropertyProvider.navPropertyETMediaOne_ETMedia,

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f15c7c7/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
index aa77abf..43b7a63 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
@@ -632,12 +632,18 @@ public class PropertyProvider {
           .setType(EntityTypeProvider.nameETMedia)
           .setCollection(true);
 
+  public static final NavigationProperty collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav_WithPartnerERKeyNavOne 
+          = new NavigationProperty()
+            .setName("NavPropertyETTwoKeyNavMany")
+            .setType(EntityTypeProvider.nameETTwoKeyNav)
+            .setCollection(true)
+            .setPartner("NavPropertyETKeyNavOne");
+  
   public static final NavigationProperty collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav = new NavigationProperty()
-          .setName("NavPropertyETTwoKeyNavMany")
-          .setType(EntityTypeProvider.nameETTwoKeyNav)
-          .setCollection(true)
-          .setPartner("NavPropertyETKeyNavOne");
-
+        .setName("NavPropertyETTwoKeyNavMany")
+        .setType(EntityTypeProvider.nameETTwoKeyNav)
+        .setCollection(true);
+  
   public static final NavigationProperty collectionNavPropertyETTwoKeyNavOne_ETTwoKeyNav = new NavigationProperty()
           .setName("NavPropertyETTwoKeyNavOne")
           .setType(EntityTypeProvider.nameETTwoKeyNav);