olingo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chall...@apache.org
Subject [49/50] [abbrv] git commit: [OLINGO-260] provided proxy entity create mechanism; still working on EntityCreateTestITCase since it seems to hang the integration tests when executed with others
Date Mon, 12 May 2014 08:39:24 GMT
[OLINGO-260] provided proxy entity create mechanism; still working on EntityCreateTestITCase since it seems to hang the integration tests when executed with others


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

Branch: refs/heads/olingo274
Commit: f1cbc4aff6f09137eb1fa83767642aee295e9e3a
Parents: ec30775
Author: fmartelli <fabio.martelli@gmail.com>
Authored: Sun May 11 18:05:39 2014 +0200
Committer: fmartelli <fabio.martelli@gmail.com>
Committed: Sun May 11 18:05:39 2014 +0200

----------------------------------------------------------------------
 .../commons/AbstractTypeInvocationHandler.java  |  71 ++-----
 .../commons/ComplexTypeInvocationHandler.java   |  95 +++++++--
 .../commons/EntityTypeInvocationHandler.java    |  91 +++++---
 .../proxy/commons/FactoryInvocationHandler.java |  84 ++++++++
 .../olingo/ext/proxy/utils/CoreUtils.java       | 132 ++++++++----
 .../olingo/ext/pojogen/AbstractUtility.java     |  12 ++
 .../src/main/resources/entityType.vm            |  29 ++-
 .../src/main/resources/v30/complexType.vm       |  23 +-
 .../src/main/resources/v40/complexType.vm       |  23 +-
 .../org/apache/olingo/fit/AbstractServices.java |  75 +++----
 .../olingo/fit/utils/AbstractUtilities.java     |  18 +-
 .../V30/CustomerInfo/16/entity.full.json        |  11 +
 .../resources/V30/CustomerInfo/16/entity.xml    |  37 ++++
 .../olingo/fit/proxy/v3/AbstractTest.java       |  22 +-
 .../fit/proxy/v3/EntityCreateTestITCase.java    | 210 +++++++++++++++++++
 .../fit/proxy/v3/EntityRetrieveTestITCase.java  |  38 +++-
 .../AllGeoCollectionTypesSet.java               |   1 +
 .../astoriadefaultservice/AllGeoTypesSet.java   |   1 +
 .../services/astoriadefaultservice/Car.java     |   1 +
 .../astoriadefaultservice/Computer.java         |   1 +
 .../astoriadefaultservice/ComputerDetail.java   |   1 +
 .../astoriadefaultservice/Customer.java         |   1 +
 .../astoriadefaultservice/CustomerInfo.java     |   1 +
 .../astoriadefaultservice/DefaultContainer.java |   1 +
 .../services/astoriadefaultservice/Driver.java  |   1 +
 .../astoriadefaultservice/LastLogin.java        |   1 +
 .../services/astoriadefaultservice/License.java |   1 +
 .../services/astoriadefaultservice/Login.java   |   1 +
 .../astoriadefaultservice/MappedEntityType.java |   1 +
 .../services/astoriadefaultservice/Message.java |   1 +
 .../MessageAttachment.java                      |   1 +
 .../services/astoriadefaultservice/Order.java   |   1 +
 .../astoriadefaultservice/OrderLine.java        |   1 +
 .../astoriadefaultservice/PageView.java         |   1 +
 .../services/astoriadefaultservice/Person.java  |   1 +
 .../astoriadefaultservice/PersonMetadata.java   |   1 +
 .../services/astoriadefaultservice/Product.java |   1 +
 .../astoriadefaultservice/ProductDetail.java    |   1 +
 .../astoriadefaultservice/ProductPhoto.java     |   1 +
 .../astoriadefaultservice/ProductReview.java    |   1 +
 .../astoriadefaultservice/RSAToken.java         |   1 +
 .../astoriadefaultservice/package-info.java     |   1 +
 .../astoriadefaultservice/types/Aliases.java    |   5 +-
 .../types/AllSpatialCollectionTypes.java        |   3 +-
 .../AllSpatialCollectionTypesCollection.java    |   1 +
 .../types/AllSpatialCollectionTypes_Simple.java |   3 +-
 ...SpatialCollectionTypes_SimpleCollection.java |   1 +
 .../types/AllSpatialTypes.java                  |   3 +-
 .../types/AllSpatialTypesCollection.java        |   1 +
 .../astoriadefaultservice/types/AuditInfo.java  |  17 +-
 .../types/BackOrderLine.java                    |   3 +-
 .../types/BackOrderLine2.java                   |   3 +-
 .../types/BackOrderLine2Collection.java         |   1 +
 .../types/BackOrderLineCollection.java          |   1 +
 .../astoriadefaultservice/types/Car.java        |   3 +-
 .../types/CarCollection.java                    |   1 +
 .../types/ComplexToCategory.java                |   5 +-
 .../types/ComplexWithAllPrimitiveTypes.java     |   5 +-
 .../astoriadefaultservice/types/Computer.java   |   7 +-
 .../types/ComputerCollection.java               |   1 +
 .../types/ComputerDetail.java                   |  17 +-
 .../types/ComputerDetailCollection.java         |   1 +
 .../types/ConcurrencyInfo.java                  |   5 +-
 .../types/ContactDetails.java                   |  41 ++--
 .../astoriadefaultservice/types/Contractor.java |   3 +-
 .../types/ContractorCollection.java             |   1 +
 .../astoriadefaultservice/types/Customer.java   |  29 ++-
 .../types/CustomerCollection.java               |   1 +
 .../types/CustomerInfo.java                     |   3 +-
 .../types/CustomerInfoCollection.java           |   1 +
 .../astoriadefaultservice/types/Dimensions.java |   5 +-
 .../types/DiscontinuedProduct.java              |  38 ++--
 .../types/DiscontinuedProductCollection.java    |   1 +
 .../astoriadefaultservice/types/Driver.java     |   3 +-
 .../types/DriverCollection.java                 |   1 +
 .../astoriadefaultservice/types/Employee.java   |   7 +-
 .../types/EmployeeCollection.java               |   1 +
 .../astoriadefaultservice/types/LastLogin.java  |   3 +-
 .../types/LastLoginCollection.java              |   1 +
 .../astoriadefaultservice/types/License.java    |   3 +-
 .../types/LicenseCollection.java                |   1 +
 .../astoriadefaultservice/types/Login.java      |   3 +-
 .../types/LoginCollection.java                  |   1 +
 .../types/MappedEntityType.java                 |  29 ++-
 .../types/MappedEntityTypeCollection.java       |   1 +
 .../astoriadefaultservice/types/Message.java    |   3 +-
 .../types/MessageAttachment.java                |   3 +-
 .../types/MessageAttachmentCollection.java      |   1 +
 .../types/MessageCollection.java                |   1 +
 .../astoriadefaultservice/types/MessageKey.java |   1 +
 .../astoriadefaultservice/types/Order.java      |  13 +-
 .../types/OrderCollection.java                  |   1 +
 .../astoriadefaultservice/types/OrderLine.java  |   3 +-
 .../types/OrderLineCollection.java              |   1 +
 .../types/OrderLineKey.java                     |   1 +
 .../astoriadefaultservice/types/PageView.java   |   3 +-
 .../types/PageViewCollection.java               |   1 +
 .../astoriadefaultservice/types/Person.java     |   3 +-
 .../types/PersonCollection.java                 |   1 +
 .../types/PersonMetadata.java                   |   3 +-
 .../types/PersonMetadataCollection.java         |   1 +
 .../astoriadefaultservice/types/Phone.java      |   5 +-
 .../astoriadefaultservice/types/Product.java    |  33 +--
 .../types/ProductCollection.java                |   1 +
 .../types/ProductDetail.java                    |   3 +-
 .../types/ProductDetailCollection.java          |   1 +
 .../types/ProductPageView.java                  |   3 +-
 .../types/ProductPageViewCollection.java        |   1 +
 .../types/ProductPhoto.java                     |   3 +-
 .../types/ProductPhotoCollection.java           |   1 +
 .../types/ProductPhotoKey.java                  |   1 +
 .../types/ProductReview.java                    |   3 +-
 .../types/ProductReviewCollection.java          |   1 +
 .../types/ProductReviewKey.java                 |   1 +
 .../astoriadefaultservice/types/RSAToken.java   |   3 +-
 .../types/RSATokenCollection.java               |   1 +
 .../types/SpecialEmployee.java                  |   3 +-
 .../types/SpecialEmployeeCollection.java        |   1 +
 .../types/package-info.java                     |   1 +
 .../services/odatawcfservice/Accounts.java      |   1 +
 .../odata/services/odatawcfservice/Boss.java    |   1 +
 .../odata/services/odatawcfservice/Company.java |   1 +
 .../services/odatawcfservice/Customers.java     |   1 +
 .../odatawcfservice/DefaultStoredPI.java        |   1 +
 .../services/odatawcfservice/Departments.java   |   1 +
 .../services/odatawcfservice/Employees.java     |   1 +
 .../odatawcfservice/InMemoryEntities.java       |   1 +
 .../services/odatawcfservice/LabourUnion.java   |   1 +
 .../services/odatawcfservice/OrderDetails.java  |   1 +
 .../odata/services/odatawcfservice/Orders.java  |   1 +
 .../odata/services/odatawcfservice/People.java  |   1 +
 .../odatawcfservice/ProductDetails.java         |   1 +
 .../odatawcfservice/ProductReviews.java         |   1 +
 .../services/odatawcfservice/Products.java      |   1 +
 .../services/odatawcfservice/PublicCompany.java |   1 +
 .../services/odatawcfservice/StoredPIs.java     |   1 +
 .../odatawcfservice/SubscriptionTemplates.java  |   1 +
 .../services/odatawcfservice/VipCustomer.java   |   1 +
 .../services/odatawcfservice/package-info.java  |   1 +
 .../odatawcfservice/types/AccessLevel.java      |   1 +
 .../services/odatawcfservice/types/Account.java |  17 +-
 .../types/AccountCollection.java                |   1 +
 .../odatawcfservice/types/AccountInfo.java      |   5 +-
 .../services/odatawcfservice/types/Address.java |   5 +-
 .../services/odatawcfservice/types/Asset.java   |   3 +-
 .../odatawcfservice/types/AssetCollection.java  |   1 +
 .../services/odatawcfservice/types/Club.java    |   3 +-
 .../odatawcfservice/types/ClubCollection.java   |   1 +
 .../services/odatawcfservice/types/Color.java   |   1 +
 .../services/odatawcfservice/types/Company.java |  17 +-
 .../odatawcfservice/types/CompanyAddress.java   |   5 +-
 .../odatawcfservice/types/CompanyCategory.java  |   1 +
 .../types/CompanyCollection.java                |   1 +
 .../odatawcfservice/types/CreditCardPI.java     |   3 +-
 .../types/CreditCardPICollection.java           |   1 +
 .../odatawcfservice/types/CreditRecord.java     |   3 +-
 .../types/CreditRecordCollection.java           |   1 +
 .../odatawcfservice/types/Customer.java         |  14 +-
 .../types/CustomerCollection.java               |   1 +
 .../odatawcfservice/types/Department.java       |   3 +-
 .../types/DepartmentCollection.java             |   1 +
 .../odatawcfservice/types/Employee.java         |  14 +-
 .../types/EmployeeCollection.java               |   1 +
 .../odatawcfservice/types/GiftCard.java         |   7 +-
 .../types/GiftCardCollection.java               |   1 +
 .../odatawcfservice/types/HomeAddress.java      |   5 +-
 .../odatawcfservice/types/LabourUnion.java      |   3 +-
 .../types/LabourUnionCollection.java            |   1 +
 .../services/odatawcfservice/types/Order.java   |   3 +-
 .../odatawcfservice/types/OrderCollection.java  |   1 +
 .../odatawcfservice/types/OrderDetail.java      |   3 +-
 .../types/OrderDetailCollection.java            |   1 +
 .../odatawcfservice/types/OrderDetailKey.java   |   1 +
 .../types/PaymentInstrument.java                |   3 +-
 .../types/PaymentInstrumentCollection.java      |   1 +
 .../services/odatawcfservice/types/Person.java  |  17 +-
 .../odatawcfservice/types/PersonCollection.java |   1 +
 .../services/odatawcfservice/types/Product.java |   7 +-
 .../types/ProductCollection.java                |   1 +
 .../odatawcfservice/types/ProductDetail.java    |   7 +-
 .../types/ProductDetailCollection.java          |   1 +
 .../odatawcfservice/types/ProductDetailKey.java |   1 +
 .../odatawcfservice/types/ProductReview.java    |   3 +-
 .../types/ProductReviewCollection.java          |   1 +
 .../odatawcfservice/types/ProductReviewKey.java |   1 +
 .../odatawcfservice/types/PublicCompany.java    |  14 +-
 .../types/PublicCompanyCollection.java          |   1 +
 .../odatawcfservice/types/Statement.java        |   3 +-
 .../types/StatementCollection.java              |   1 +
 .../odatawcfservice/types/StoredPI.java         |   3 +-
 .../types/StoredPICollection.java               |   1 +
 .../odatawcfservice/types/Subscription.java     |   3 +-
 .../types/SubscriptionCollection.java           |   1 +
 .../odatawcfservice/types/package-info.java     |   1 +
 .../apache/olingo/fit/v3/BatchTestITCase.java   |  13 ++
 195 files changed, 1174 insertions(+), 428 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractTypeInvocationHandler.java
index d1ab039..f10cb03 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractTypeInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractTypeInvocationHandler.java
@@ -31,8 +31,6 @@ import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
 import org.apache.olingo.client.core.uri.URIUtils;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
-import org.apache.olingo.commons.api.domain.CommonODataProperty;
-import org.apache.olingo.commons.api.domain.ODataComplexValue;
 import org.apache.olingo.commons.api.domain.ODataInlineEntity;
 import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
 import org.apache.olingo.commons.api.domain.ODataLink;
@@ -40,19 +38,25 @@ import org.apache.olingo.commons.api.domain.ODataLinked;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.ext.proxy.EntityContainerFactory;
 import org.apache.olingo.ext.proxy.api.AbstractEntityCollection;
-import org.apache.olingo.ext.proxy.api.annotations.ComplexType;
 import org.apache.olingo.ext.proxy.api.annotations.EntityType;
 import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
 import org.apache.olingo.ext.proxy.api.annotations.Property;
 import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
 import org.apache.olingo.ext.proxy.context.EntityContext;
 import org.apache.olingo.ext.proxy.utils.ClassUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public abstract class AbstractTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?>>
         extends AbstractInvocationHandler<C> {
 
   private static final long serialVersionUID = 2629912294765040037L;
 
+  /**
+   * Logger.
+   */
+  protected static final Logger LOG = LoggerFactory.getLogger(AbstractTypeInvocationHandler.class);
+
   protected final Class<?> typeRef;
 
   protected final EntityContext entityContext = EntityContainerFactory.getContext().entityContext();
@@ -104,11 +108,17 @@ public abstract class AbstractTypeInvocationHandler<C extends CommonEdmEnabledOD
               Thread.currentThread().getContextClassLoader(),
               new Class<?>[] {returnType},
               OperationInvocationHandler.getInstance(targetHandler));
+    } else if ("factory".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
+      final Class<?> returnType = method.getReturnType();
+
+      return Proxy.newProxyInstance(
+              Thread.currentThread().getContextClassLoader(),
+              new Class<?>[] {returnType},
+              FactoryInvocationHandler.getInstance(targetHandler, this));
     } else if (method.getName().startsWith("get")) {
       // Assumption: for each getter will always exist a setter and viceversa.
       // get method annotation and check if it exists as expected
       final Object res;
-
       final Method getter = typeRef.getMethod(method.getName());
 
       final Property property = ClassUtils.getAnnotation(Property.class, getter);
@@ -152,22 +162,6 @@ public abstract class AbstractTypeInvocationHandler<C extends CommonEdmEnabledOD
       }
 
       return ClassUtils.returnVoid();
-    } else if (method.getName().startsWith("new")) {
-      // get the corresponding getter method (see assumption above)
-      final String getterName = method.getName().replaceFirst("new", "get");
-      final Method getter = typeRef.getMethod(getterName);
-
-      final Property property = ClassUtils.getAnnotation(Property.class, getter);
-      if (property == null) {
-        throw new UnsupportedOperationException("Unsupported method " + method.getName());
-      }
-
-      final ComplexTypeInvocationHandler<C> complexTypeHandler = newComplex(property.name(), getter.getReturnType());
-
-      return Proxy.newProxyInstance(
-              Thread.currentThread().getContextClassLoader(),
-              new Class<?>[] {getter.getReturnType()},
-              complexTypeHandler);
     } else {
       throw new UnsupportedOperationException("Method not found: " + method);
     }
@@ -193,39 +187,6 @@ public abstract class AbstractTypeInvocationHandler<C extends CommonEdmEnabledOD
     }
   }
 
-  @SuppressWarnings({"unchecked"})
-  protected ComplexTypeInvocationHandler<C> newComplex(final String propertyName, final Class<?> reference) {
-    final Class<?> complexTypeRef;
-    final boolean isCollection;
-    if (Collection.class.isAssignableFrom(reference)) {
-      complexTypeRef = ClassUtils.extractTypeArg(reference);
-      isCollection = true;
-    } else {
-      complexTypeRef = reference;
-      isCollection = false;
-    }
-
-    final ComplexType annotation = complexTypeRef.getAnnotation(ComplexType.class);
-    if (annotation == null) {
-      throw new IllegalArgumentException("Invalid complex type " + complexTypeRef);
-    }
-
-    final FullQualifiedName typeName =
-            new FullQualifiedName(ClassUtils.getNamespace(complexTypeRef), annotation.name());
-
-    final ODataComplexValue<? extends CommonODataProperty> complex =
-            client.getObjectFactory().newComplexValue(typeName.toString());
-
-    final ComplexTypeInvocationHandler<C> handler = (ComplexTypeInvocationHandler<C>) ComplexTypeInvocationHandler.
-            getInstance(complex, complexTypeRef, targetHandler);
-
-    attach(AttachedEntityStatus.CHANGED);
-
-    addPropertyChanges(propertyName, handler, isCollection);
-
-    return handler;
-  }
-
   protected abstract Object getNavigationPropertyValue(final NavigationProperty property, final Method getter);
 
   protected Object retriveNavigationProperty(final NavigationProperty property, final Method getter) {
@@ -296,7 +257,7 @@ public abstract class AbstractTypeInvocationHandler<C extends CommonEdmEnabledOD
   }
 
   public void addAdditionalProperty(final String name, final Object value) {
-    addPropertyChanges(name, value, false);
+    addPropertyChanges(name, value);
     attach(AttachedEntityStatus.CHANGED);
   }
 
@@ -338,7 +299,7 @@ public abstract class AbstractTypeInvocationHandler<C extends CommonEdmEnabledOD
 
   protected abstract void setPropertyValue(final Property property, final Object value);
 
-  protected abstract void addPropertyChanges(final String name, final Object value, final boolean isCollection);
+  protected abstract void addPropertyChanges(final String name, final Object value);
 
   protected abstract void addLinkChanges(final NavigationProperty navProp, final Object value);
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
index 76bfe7f..dfb1271 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
@@ -20,8 +20,10 @@ package org.apache.olingo.ext.proxy.commons;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -30,6 +32,7 @@ import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.domain.ODataComplexValue;
 import org.apache.olingo.commons.api.domain.ODataLinked;
+import org.apache.olingo.commons.api.domain.ODataValue;
 import org.apache.olingo.commons.api.edm.EdmElement;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
@@ -45,13 +48,41 @@ public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<
 
   private static final long serialVersionUID = 2629912294765040037L;
 
+  public static ComplexTypeInvocationHandler<?> getInstance(
+          final CommonEdmEnabledODataClient<?> client,
+          final String propertyName,
+          final Class<?> reference,
+          final EntityTypeInvocationHandler<?> handler) {
+    final Class<?> complexTypeRef;
+    if (Collection.class.isAssignableFrom(reference)) {
+      complexTypeRef = ClassUtils.extractTypeArg(reference);
+    } else {
+      complexTypeRef = reference;
+    }
+
+    final ComplexType annotation = complexTypeRef.getAnnotation(ComplexType.class);
+    if (annotation == null) {
+      throw new IllegalArgumentException("Invalid complex type " + complexTypeRef);
+    }
+
+    final FullQualifiedName typeName =
+            new FullQualifiedName(ClassUtils.getNamespace(complexTypeRef), annotation.name());
+
+    final ODataComplexValue<? extends CommonODataProperty> complex =
+            client.getObjectFactory().newComplexValue(typeName.toString());
+
+    return (ComplexTypeInvocationHandler<?>) ComplexTypeInvocationHandler.getInstance(
+            client, complex, complexTypeRef, handler);
+  }
+
   @SuppressWarnings({"unchecked", "rawtypes"})
   static ComplexTypeInvocationHandler<?> getInstance(
+          final CommonEdmEnabledODataClient<?> client,
           final ODataComplexValue<?> complex,
           final Class<?> typeRef,
           final EntityTypeInvocationHandler<?> handler) {
 
-    return new ComplexTypeInvocationHandler(handler.targetHandler.getClient(), complex, typeRef, handler);
+    return new ComplexTypeInvocationHandler(client, complex, typeRef, handler);
   }
 
   public ComplexTypeInvocationHandler(
@@ -83,19 +114,38 @@ public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<
       final Object res;
 
       final CommonODataProperty property = getComplex().get(name);
-
-      if (property.hasComplexValue()) {
+      if (property == null) {
+        res = null;
+      } else if (property.hasComplexValue()) {
         res = Proxy.newProxyInstance(
                 Thread.currentThread().getContextClassLoader(),
                 new Class<?>[] {(Class<?>) type},
-                newComplex(name, (Class<?>) type));
-
-        CoreUtils.populate(
-                client.getCachedEdm(),
-                res,
-                (Class<?>) type,
-                Property.class,
-                property.getValue().asComplex().iterator());
+                ComplexTypeInvocationHandler.getInstance(
+                client, property.getValue().asComplex(), (Class<?>) type, targetHandler));
+
+      } else if (property.hasCollectionValue()) {
+        final ParameterizedType collType = (ParameterizedType) type;
+        final Class<?> collItemClass = (Class<?>) collType.getActualTypeArguments()[0];
+
+        final ArrayList<Object> collection = new ArrayList<Object>();
+
+        final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
+        while (collPropItor.hasNext()) {
+          final ODataValue value = collPropItor.next();
+          if (value.isPrimitive()) {
+            collection.add(CoreUtils.primitiveValueToObject(value.asPrimitive()));
+          } else if (value.isComplex()) {
+            final Object collItem = Proxy.newProxyInstance(
+                    Thread.currentThread().getContextClassLoader(),
+                    new Class<?>[] {collItemClass},
+                    ComplexTypeInvocationHandler.getInstance(
+                    client, value.asComplex(), collItemClass, targetHandler));
+
+            collection.add(collItem);
+          }
+        }
+
+        res = collection;
       } else {
         res = type == null
                 ? CoreUtils.getValueFromProperty(client, property)
@@ -131,17 +181,34 @@ public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<
   }
 
   @Override
+  @SuppressWarnings("unchecked")
   protected void setPropertyValue(final Property property, final Object value) {
     final FullQualifiedName fqn =
             new FullQualifiedName(ClassUtils.getNamespace(typeRef), typeRef.getAnnotation(ComplexType.class).name());
 
     final EdmElement edmProperty = client.getCachedEdm().getComplexType(fqn).getProperty(property.name());
 
+    final Object toBeAdded;
+
+    if (value == null) {
+      toBeAdded = null;
+    } else if (Collection.class.isAssignableFrom(value.getClass())) {
+      toBeAdded = new ArrayList<Object>();
+      for (Object obj : (Collection) value) {
+        ((Collection) toBeAdded).add(obj instanceof Proxy ? Proxy.getInvocationHandler(obj) : obj);
+      }
+    } else if (value instanceof Proxy) {
+      toBeAdded = Proxy.getInvocationHandler(value);
+    } else {
+      toBeAdded = value;
+    }
+
     final EdmTypeInfo type = new EdmTypeInfo.Builder().
             setEdm(client.getCachedEdm()).setTypeExpression(
-                    edmProperty.isCollection() ? "Collection(" + property.type() + ")" : property.type()).build();
+            edmProperty.isCollection() ? "Collection(" + property.type() + ")" : property.type()).build();
 
-    client.getBinder().add(getComplex(), CoreUtils.getODataProperty(client, property.name(), type, value));
+    client.getBinder().add(
+            getComplex(), CoreUtils.getODataProperty(client, property.name(), type, toBeAdded));
 
     if (targetHandler != null && !entityContext.isAttached(targetHandler)) {
       entityContext.attach(targetHandler, AttachedEntityStatus.CHANGED);
@@ -158,7 +225,7 @@ public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<
   }
 
   @Override
-  protected void addPropertyChanges(final String name, final Object value, final boolean isCollection) {
+  protected void addPropertyChanges(final String name, final Object value) {
     // do nothing ....
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
index 242e853..449a8d1 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
@@ -21,6 +21,7 @@ package org.apache.olingo.ext.proxy.commons;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import java.net.URI;
@@ -28,6 +29,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import org.apache.commons.io.IOUtils;
@@ -38,6 +40,7 @@ import org.apache.olingo.client.core.uri.URIUtils;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.domain.ODataLinked;
+import org.apache.olingo.commons.api.domain.ODataValue;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ODataMediaFormat;
@@ -107,7 +110,7 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
             containerHandler.getEntityContainerName(),
             entitySetName,
             entity.getTypeName(),
-            CoreUtils.getKey(client.getCachedEdm(), typeRef, entity));
+            CoreUtils.getKey(client, typeRef, entity));
 
     this.stream = null;
   }
@@ -120,7 +123,7 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
             getUUID().getContainerName(),
             getUUID().getEntitySetName(),
             getUUID().getName(),
-            CoreUtils.getKey(client.getCachedEdm(), typeRef, entity));
+            CoreUtils.getKey(client, typeRef, entity));
 
     this.propertyChanges.clear();
     this.linkChanges.clear();
@@ -193,35 +196,52 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
   protected Object getPropertyValue(final String name, final Type type) {
     try {
       final Object res;
-
       final CommonODataProperty property = entity.getProperty(name);
 
       if (propertyChanges.containsKey(name)) {
-        res = property.hasComplexValue()
-                ? Proxy.newProxyInstance(
-                Thread.currentThread().getContextClassLoader(),
-                new Class<?>[] {(Class<?>) type},
-                (ComplexTypeInvocationHandler<?>) propertyChanges.get(name))
-                : propertyChanges.get(name);
+        res = propertyChanges.get(name);
+      } else if (property == null) {
+        res = null;
       } else if (property.hasComplexValue()) {
         res = Proxy.newProxyInstance(
                 Thread.currentThread().getContextClassLoader(),
                 new Class<?>[] {(Class<?>) type},
-                newComplex(name, (Class<?>) type));
-
-        CoreUtils.populate(
-                client.getCachedEdm(),
-                res,
-                (Class<?>) type,
-                Property.class,
-                property.getValue().asComplex().iterator());
+                ComplexTypeInvocationHandler.getInstance(
+                client, property.getValue().asComplex(), (Class<?>) type, this));
+
+        addPropertyChanges(name, res);
+      } else if (property.hasCollectionValue()) {
+        final ParameterizedType collType = (ParameterizedType) type;
+        final Class<?> collItemClass = (Class<?>) collType.getActualTypeArguments()[0];
+
+        final ArrayList<Object> collection = new ArrayList<Object>();
+
+        final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
+        while (collPropItor.hasNext()) {
+          final ODataValue value = collPropItor.next();
+          if (value.isPrimitive()) {
+            collection.add(CoreUtils.primitiveValueToObject(value.asPrimitive()));
+          } else if (value.isComplex()) {
+            final Object collItem = Proxy.newProxyInstance(
+                    Thread.currentThread().getContextClassLoader(),
+                    new Class<?>[] {collItemClass},
+                    ComplexTypeInvocationHandler.getInstance(
+                    client, value.asComplex(), collItemClass, this));
+
+            collection.add(collItem);
+          }
+        }
+
+        res = collection;
+
+        addPropertyChanges(name, res);
       } else {
         res = type == null
                 ? CoreUtils.getValueFromProperty(client, property)
                 : CoreUtils.getValueFromProperty(client, property, type);
 
         if (res != null) {
-          addPropertyChanges(name, res, false);
+          addPropertyChanges(name, res);
         }
       }
 
@@ -256,11 +276,27 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
   }
 
   @Override
+  @SuppressWarnings("unchecked")
   protected void setPropertyValue(final Property property, final Object value) {
     if (property.type().equalsIgnoreCase(EdmPrimitiveTypeKind.Stream.toString())) {
       setStreamedProperty(property, (InputStream) value);
     } else {
-      addPropertyChanges(property.name(), value, false);
+      final Object toBeAdded;
+
+      if (value == null) {
+        toBeAdded = null;
+      } else if (Collection.class.isAssignableFrom(value.getClass())) {
+        toBeAdded = new ArrayList<Object>();
+        for (Object obj : (Collection) value) {
+          ((Collection) toBeAdded).add(obj instanceof Proxy ? Proxy.getInvocationHandler(obj) : obj);
+        }
+      } else if (value instanceof Proxy) {
+        toBeAdded = Proxy.getInvocationHandler(value);
+      } else {
+        toBeAdded = value;
+      }
+
+      addPropertyChanges(property.name(), toBeAdded);
     }
 
     attach(AttachedEntityStatus.CHANGED);
@@ -360,22 +396,9 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
 
   @Override
   @SuppressWarnings("unchecked")
-  protected void addPropertyChanges(final String name, final Object value, final boolean isCollection) {
+  protected void addPropertyChanges(final String name, final Object value) {
     int checkpoint = propertyChanges.hashCode();
-
-    if (isCollection) {
-      Object collItem = propertyChanges.get(name);
-
-      if (collItem == null) {
-        collItem = new ArrayList<Object>();
-        propertyChanges.put(name, collItem);
-      }
-
-      ((Collection<Object>) collItem).add(value);
-    } else {
-      propertyChanges.put(name, value);
-    }
-
+    propertyChanges.put(name, value);
     updatePropertiesTag(checkpoint);
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/FactoryInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/FactoryInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/FactoryInvocationHandler.java
new file mode 100644
index 0000000..5cfe52e
--- /dev/null
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/FactoryInvocationHandler.java
@@ -0,0 +1,84 @@
+/*
+ * 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.ext.proxy.commons;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
+import org.apache.olingo.ext.proxy.api.OperationExecutor;
+import org.apache.olingo.ext.proxy.api.annotations.Property;
+import org.apache.olingo.ext.proxy.utils.ClassUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class FactoryInvocationHandler<C extends CommonEdmEnabledODataClient<?>> extends AbstractInvocationHandler<C>
+        implements OperationExecutor {
+
+  private static final long serialVersionUID = 2629912294765040027L;
+
+  /**
+   * Logger.
+   */
+  private static final Logger LOG = LoggerFactory.getLogger(FactoryInvocationHandler.class);
+
+  private final EntityTypeInvocationHandler<C> entityHandler;
+
+  private final AbstractTypeInvocationHandler<C> invokerHandler;
+
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  static FactoryInvocationHandler<?> getInstance(
+          final EntityTypeInvocationHandler<?> entityHandler,
+          final AbstractTypeInvocationHandler<?> targetHandler) {
+    return new FactoryInvocationHandler(entityHandler, targetHandler);
+  }
+
+  @SuppressWarnings("unchecked")
+  private FactoryInvocationHandler(
+          final EntityTypeInvocationHandler<C> entityHandler,
+          final AbstractTypeInvocationHandler<C> targetHandler) {
+    super(targetHandler.containerHandler.getClient(), targetHandler.containerHandler);
+    this.invokerHandler = targetHandler;
+    this.entityHandler = entityHandler;
+  }
+
+  @Override
+  @SuppressWarnings("unchecked")
+  public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+    if (isSelfMethod(method, args)) {
+      return invokeSelfMethod(method, args);
+    } else if (method.getName().startsWith("new")) {
+      final String getterName = method.getName().replaceFirst("new", "get");
+      final Method getter = invokerHandler.getTypeRef().getMethod(getterName);
+      final Property property = ClassUtils.getAnnotation(Property.class, getter);
+      if (property == null) {
+        throw new UnsupportedOperationException("Unsupported method " + method.getName());
+      }
+
+      final ComplexTypeInvocationHandler<?> complexTypeHandler =
+              ComplexTypeInvocationHandler.getInstance(client, property.name(), method.getReturnType(), entityHandler);
+
+      return Proxy.newProxyInstance(
+              Thread.currentThread().getContextClassLoader(),
+              new Class<?>[] {method.getReturnType()},
+              complexTypeHandler);
+    } else {
+      throw new UnsupportedOperationException("Method not found: " + method);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
index 1adeeb3..ea2832b 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.ext.proxy.utils;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
@@ -41,7 +42,7 @@ import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.domain.ODataLink;
 import org.apache.olingo.commons.api.domain.ODataPrimitiveValue;
 import org.apache.olingo.commons.api.domain.ODataValue;
-import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmElement;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
@@ -51,6 +52,7 @@ import org.apache.olingo.ext.proxy.api.annotations.ComplexType;
 import org.apache.olingo.ext.proxy.api.annotations.CompoundKeyElement;
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 import org.apache.olingo.ext.proxy.api.annotations.Property;
+import org.apache.olingo.ext.proxy.commons.AbstractTypeInvocationHandler;
 import org.apache.olingo.ext.proxy.commons.ComplexTypeInvocationHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -97,13 +99,20 @@ public final class CoreUtils {
     } else if (type.isComplexType()) {
       value = client.getObjectFactory().newComplexValue(type.getFullQualifiedName().toString());
 
-      if (obj instanceof ComplexTypeInvocationHandler<?>) {
-        final Class<?> typeRef = ((ComplexTypeInvocationHandler<?>)obj).getTypeRef();
-          final Object complex = Proxy.newProxyInstance(
-                  Thread.currentThread().getContextClassLoader(),
-                  new Class<?>[] {typeRef},
-                  (ComplexTypeInvocationHandler<?>)obj);
-      
+      final Object oo;
+      if (obj instanceof Proxy) {
+        oo = Proxy.getInvocationHandler(obj);
+      } else {
+        oo = obj;
+      }
+
+      if (oo instanceof ComplexTypeInvocationHandler<?>) {
+        final Class<?> typeRef = ((ComplexTypeInvocationHandler<?>) oo).getTypeRef();
+        final Object complex = Proxy.newProxyInstance(
+                Thread.currentThread().getContextClassLoader(),
+                new Class<?>[] {typeRef},
+                (ComplexTypeInvocationHandler<?>) oo);
+
         for (Method method : typeRef.getMethods()) {
           final Property complexPropertyAnn = method.getAnnotation(Property.class);
           try {
@@ -113,12 +122,13 @@ public final class CoreUtils {
             }
           } catch (Exception ignore) {
             // ignore value
-            LOG.warn("Error attaching complex field '{}'", complexPropertyAnn.name(), ignore);
+            LOG.warn("Error attaching complex {} for field '{}.{}'",
+                    type.getFullQualifiedName(), typeRef.getName(), complexPropertyAnn.name(), ignore);
           }
         }
       } else {
         throw new IllegalArgumentException(
-                "Object '" + obj.getClass().getSimpleName() + "' is not a complex value");
+                "Object '" + oo.getClass().getSimpleName() + "' is not a complex value");
       }
     } else if (type.isEnumType()) {
       if (client.getServiceVersion().compareTo(ODataServiceVersion.V30) <= 0) {
@@ -135,17 +145,14 @@ public final class CoreUtils {
     return value;
   }
 
-  private static CommonODataProperty getODataProperty(
+  private static CommonODataProperty getODataEntityProperty(
           final CommonEdmEnabledODataClient<?> client,
           final FullQualifiedName entity,
           final String property,
           final Object obj) {
 
-    final EdmType edmType = client.getCachedEdm().getEntityType(entity).getProperty(property).getType();
-    final EdmTypeInfo type = new EdmTypeInfo.Builder().
-            setEdm(client.getCachedEdm()).setTypeExpression(edmType.getFullQualifiedName().toString()).build();
-
-    return getODataProperty(client, property, type, obj);
+    final EdmElement edmProperty = client.getCachedEdm().getEntityType(entity).getProperty(property);
+    return getODataProperty(client, edmProperty, property, obj);
   }
 
   private static CommonODataProperty getODataComplexProperty(
@@ -154,9 +161,22 @@ public final class CoreUtils {
           final String property,
           final Object obj) {
 
-    final EdmType edmType = client.getCachedEdm().getComplexType(complex).getProperty(property).getType();
-    final EdmTypeInfo type = new EdmTypeInfo.Builder().
-            setEdm(client.getCachedEdm()).setTypeExpression(edmType.getFullQualifiedName().toString()).build();
+    final EdmElement edmProperty = client.getCachedEdm().getComplexType(complex).getProperty(property);
+    return getODataProperty(client, edmProperty, property, obj);
+  }
+
+  private static CommonODataProperty getODataProperty(
+          final CommonEdmEnabledODataClient<?> client,
+          final EdmElement edmProperty,
+          final String property,
+          final Object obj) {
+
+    final EdmType edmType = edmProperty.getType();
+
+    final EdmTypeInfo type = new EdmTypeInfo.Builder().setEdm(client.getCachedEdm()).setTypeExpression(
+            edmProperty.isCollection()
+            ? "Collection(" + edmType.getFullQualifiedName().toString() + ")"
+            : edmType.getFullQualifiedName().toString()).build();
 
     return getODataProperty(client, property, type, obj);
   }
@@ -184,8 +204,8 @@ public final class CoreUtils {
         } else {
           oprop = ((org.apache.olingo.commons.api.domain.v4.ODataObjectFactory) client.getObjectFactory()).
                   newEnumProperty(name,
-                          ((org.apache.olingo.commons.api.domain.v4.ODataValue) getODataValue(client, type, obj)).
-                          asEnum());
+                  ((org.apache.olingo.commons.api.domain.v4.ODataValue) getODataValue(client, type, obj)).
+                  asEnum());
         }
       } else {
         throw new UnsupportedOperationException("Usupported object type " + type.getFullQualifiedName());
@@ -211,11 +231,11 @@ public final class CoreUtils {
       }
 
       ((List<CommonODataProperty>) entity.getProperties()).add(
-              getODataProperty(client, entity.getTypeName(), property.getKey(), property.getValue()));
+              getODataEntityProperty(client, entity.getTypeName(), property.getKey(), property.getValue()));
     }
   }
 
-  private static Object primitiveValueToObject(final ODataPrimitiveValue value) {
+  public static Object primitiveValueToObject(final ODataPrimitiveValue value) {
     Object obj;
 
     try {
@@ -239,7 +259,7 @@ public final class CoreUtils {
   }
 
   public static Object getKey(
-          final Edm metadata, final Class<?> entityTypeRef, final CommonODataEntity entity) {
+          final CommonEdmEnabledODataClient<?> client, final Class<?> entityTypeRef, final CommonODataEntity entity) {
 
     Object res = null;
 
@@ -253,7 +273,7 @@ public final class CoreUtils {
       } else {
         try {
           res = keyRef.newInstance();
-          populate(metadata, res, CompoundKeyElement.class, entity.getProperties().iterator());
+          populate(client, res, CompoundKeyElement.class, entity.getProperties().iterator());
         } catch (Exception e) {
           LOG.error("Error population compound key {}", keyRef.getSimpleName(), e);
           throw new IllegalArgumentException("Cannot populate compound key");
@@ -265,19 +285,30 @@ public final class CoreUtils {
   }
 
   public static void populate(
-          final Edm metadata,
+          final CommonEdmEnabledODataClient<?> client,
           final Object bean,
           final Class<? extends Annotation> getterAnn,
           final Iterator<? extends CommonODataProperty> propItor) {
 
     if (bean != null) {
-      populate(metadata, bean, bean.getClass(), getterAnn, propItor);
+      final Class<?> typeRef;
+      if (bean instanceof Proxy) {
+        final InvocationHandler handler = Proxy.getInvocationHandler(bean);
+        if (handler instanceof AbstractTypeInvocationHandler) {
+          typeRef = ((ComplexTypeInvocationHandler<?>) handler).getTypeRef();
+        } else {
+          throw new IllegalStateException("Invalid bean " + bean);
+        }
+      } else {
+        typeRef = bean.getClass();
+      }
+      populate(client, bean, typeRef, getterAnn, propItor);
     }
   }
 
   @SuppressWarnings({"unchecked"})
   public static void populate(
-          final Edm metadata,
+          final CommonEdmEnabledODataClient<?> client,
           final Object bean,
           final Class<?> reference,
           final Class<? extends Annotation> getterAnn,
@@ -296,16 +327,18 @@ public final class CoreUtils {
           try {
             if (property.hasNullValue()) {
               setPropertyValue(bean, getter, null);
-            }
-            if (property.hasPrimitiveValue()) {
+            } else if (property.hasPrimitiveValue()) {
               setPropertyValue(bean, getter, primitiveValueToObject(property.getPrimitiveValue()));
-            }
-            if (property.hasComplexValue()) {
-              final Object complex = getter.getReturnType().newInstance();
-              populate(metadata, complex, Property.class, property.getValue().asComplex().iterator());
+            } else if (property.hasComplexValue()) {
+              final Object complex = Proxy.newProxyInstance(
+                      Thread.currentThread().getContextClassLoader(),
+                      new Class<?>[] {getter.getReturnType()},
+                      ComplexTypeInvocationHandler.getInstance(
+                      client, property.getName(), getter.getReturnType(), null));
+
+              populate(client, complex, Property.class, property.getValue().asComplex().iterator());
               setPropertyValue(bean, getter, complex);
-            }
-            if (property.hasCollectionValue()) {
+            } else if (property.hasCollectionValue()) {
               final ParameterizedType collType = (ParameterizedType) getter.getGenericReturnType();
               final Class<?> collItemClass = (Class<?>) collType.getActualTypeArguments()[0];
 
@@ -320,10 +353,14 @@ public final class CoreUtils {
                 final ODataValue value = collPropItor.next();
                 if (value.isPrimitive()) {
                   collection.add(primitiveValueToObject(value.asPrimitive()));
-                }
-                if (value.isComplex()) {
-                  final Object collItem = collItemClass.newInstance();
-                  populate(metadata, collItem, Property.class, value.asComplex().iterator());
+                } else if (value.isComplex()) {
+                  final Object collItem = Proxy.newProxyInstance(
+                          Thread.currentThread().getContextClassLoader(),
+                          new Class<?>[] {collItemClass},
+                          ComplexTypeInvocationHandler.getInstance(
+                          client, property.getName(), collItemClass, null));
+
+                  populate(client, collItem, Property.class, value.asComplex().iterator());
                   collection.add(collItem);
                 }
               }
@@ -356,14 +393,14 @@ public final class CoreUtils {
         }
         if (odataValue.isComplex()) {
           final Object collItem =
-                  buildComplexInstance(client.getCachedEdm(), property.getName(), odataValue.asComplex().iterator());
+                  buildComplexInstance(client, property.getName(), odataValue.asComplex().iterator());
           ((Collection) value).add(collItem);
         }
       }
     } else if (property.hasPrimitiveValue()) {
       value = primitiveValueToObject(property.getPrimitiveValue());
     } else if (property.hasComplexValue()) {
-      value = buildComplexInstance(client.getCachedEdm(), property.getValue().asComplex().getTypeName(),
+      value = buildComplexInstance(client, property.getValue().asComplex().getTypeName(),
               property.getValue().asComplex().iterator());
     } else {
       throw new IllegalArgumentException("Invalid property " + property);
@@ -374,14 +411,16 @@ public final class CoreUtils {
 
   @SuppressWarnings("unchecked")
   private static <C extends AbstractComplexType> C buildComplexInstance(
-          final Edm metadata, final String name, final Iterator<CommonODataProperty> properties) {
+          final CommonEdmEnabledODataClient<?> client,
+          final String name,
+          final Iterator<CommonODataProperty> properties) {
 
     for (C complex : (Iterable<C>) ServiceLoader.load(AbstractComplexType.class)) {
       final ComplexType ann = complex.getClass().getAnnotation(ComplexType.class);
       final String fn = ann == null ? null : ClassUtils.getNamespace(complex.getClass()) + "." + ann.name();
 
       if (name.equals(fn)) {
-        populate(metadata, complex, Property.class, properties);
+        populate(client, complex, Property.class, properties);
         return complex;
       }
     }
@@ -391,7 +430,8 @@ public final class CoreUtils {
 
   @SuppressWarnings({"unchecked", "rawtypes"})
   public static Object getValueFromProperty(
-          final CommonEdmEnabledODataClient<?> client, final CommonODataProperty property, final Type type)
+          final CommonEdmEnabledODataClient<?> client,
+          final CommonODataProperty property, final Type type)
           throws InstantiationException, IllegalAccessException {
 
     final Object value;
@@ -415,7 +455,7 @@ public final class CoreUtils {
                   Thread.currentThread().getContextClassLoader(),
                   new Class<?>[] {collItemClass},
                   new ComplexTypeInvocationHandler(client, odataValue.asComplex(), collItemClass, null));
-          populate(client.getCachedEdm(), collItem, Property.class, odataValue.asComplex().iterator());
+          populate(client, collItem, Property.class, odataValue.asComplex().iterator());
           ((Collection) value).add(collItem);
         }
       }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
index 052f415..2930ace 100644
--- a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
+++ b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
@@ -36,6 +36,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmFunction;
 import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
 import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.EdmOperation;
 import org.apache.olingo.commons.api.edm.EdmParameter;
 import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.edm.EdmSchema;
@@ -205,6 +206,17 @@ public abstract class AbstractUtility {
 
     return result;
   }
+  
+  public List<EdmOperation> justInheritedOperationsBoundTo(final EdmEntityType entity){
+    final List<EdmOperation> result = new ArrayList<EdmOperation>();
+    if(entity.getBaseType()!=null){
+      result.addAll(getFunctionsBoundTo(entity.getBaseType().getName(), false));
+      result.addAll(getActionsBoundTo(entity.getBaseType().getName(), false));
+      result.addAll(justInheritedOperationsBoundTo(entity.getBaseType()));
+    }
+    
+    return result;
+  }
 
   public List<EdmAction> getActionsBoundTo(final String typeExpression, final boolean collection) {
     final List<EdmAction> result = new ArrayList<EdmAction>();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/entityType.vm b/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
index 3386d6b..82ef821 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
@@ -69,6 +69,7 @@ public interface $utility.capitalize($entityType.Name)
     #if(!$keys.add($key.KeyPropertyName)) #stop #end
 #end
 
+#set( $complexProps = [] )
 #foreach($propertyName in $entityType.PropertyNames)
     #set($property = $entityType.getProperty($propertyName))
     #set($fcprops = $utility.getFcProperties($property) )
@@ -96,7 +97,7 @@ public interface $utility.capitalize($entityType.Name)
 
     void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));    
     #if($utility.isComplex($property.Type.FullQualifiedName))#*
-      *#$utility.getJavaType($property.Type) new$utility.capitalize($property.Name)();
+      *##set( $adding = $complexProps.add($property) )
     #end
 
 #end
@@ -125,10 +126,15 @@ public interface $utility.capitalize($entityType.Name)
 
 #set( $functions = $utility.getFunctionsBoundTo($entityType.Name, false) )
 #set( $actions = $utility.getActionsBoundTo($entityType.Name, false) )
-#if( $functions.size() > 0 || $actions.size() > 0 )
+#set( $inherited = $utility.justInheritedOperationsBoundTo($entityType).size())
+#if( $inherited.size() > 0 || $functions.size() > 0 || $actions.size() > 0 )
+    #if($inherited.size() > 0)
+    @Overide
+    #end
     Operations operations();
 
-    public interface Operations {
+    interface Operations #if($inherited.size() > 0)
+           extends ${utility.getJavaType($entityType.getBaseType())}.Operations#end{
     #foreach($operation in $functions)
       @Operation(name = "$operation.Name",
                     type = OperationType.FUNCTION,
@@ -169,4 +175,21 @@ public interface $utility.capitalize($entityType.Name)
     #end
     }
 #end
+
+#if( $complexProps.size() > 0 )
+    #if( $entityType.baseType )
+    @Override
+    #end
+    ComplexFactory factory();
+
+    interface ComplexFactory #if( $entityType.baseType )
+           extends ${utility.getJavaType($entityType.getBaseType())}.ComplexFactory#end{
+    #foreach($property in $complexProps)
+         @Property(name = "$property.Name",
+                   type = "$property.Type.FullQualifiedName.toString()")
+         $utility.getJavaType($property.Type) new$utility.capitalize($property.Name)();
+
+    #end
+    }
+#end   
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm b/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
index 7a5c6cc..4f0f86b 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
@@ -18,8 +18,10 @@
  *#
 @Namespace("$namespace")
 @ComplexType(name = "$complexType.Name")
-public interface $utility.capitalize($complexType.Name) extends Serializable {
+public interface $utility.capitalize($complexType.Name) 
+    extends #if($complexType.getBaseType())$utility.getJavaType($complexType.getBaseType().getFullQualifiedName().toString())#{else}Serializable#end {
 
+#set( $complexProps = [] )
 #foreach($propertyName in $complexType.PropertyNames)
     #set($property = $complexType.getProperty($propertyName))
 
@@ -29,7 +31,24 @@ public interface $utility.capitalize($complexType.Name) extends Serializable {
     void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));
 
     #if($utility.isComplex($property.Type.FullQualifiedName))#*
-      *#$utility.getJavaType($property.Type) new$utility.capitalize($property.Name)();
+      *##set( $adding = $complexProps.add($property) )
     #end
 
 #end
+
+#if( $complexProps.size() > 0 )
+    #if( $complexType.baseType )
+    @Override
+    #end
+    ComplexFactory factory();
+
+    interface ComplexFactory #if( $complexType.baseType )
+           extends ${utility.getJavaType($complexType.getBaseType())}.ComplexFactory#end{
+    #foreach($property in $complexProps)
+         @Property(name = "$property.Name",
+                   type = "$property.Type.FullQualifiedName.toString()")
+         $utility.getJavaType($property.Type) new$utility.capitalize($property.Name)();
+
+    #end
+    }
+#end  

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm b/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
index dd74ade..e3d2a55 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
@@ -21,8 +21,10 @@
         isOpenType = $complexType.isOpenType(),
         isAbstract = $complexType.Abstract#if($complexType.getBaseType()),
         baseType = "$complexType.getBaseType().getFullQualifiedName().toString()"#end)
-public interface $utility.capitalize($complexType.Name) extends #if($complexType.getBaseType())$utility.getJavaType($complexType.getBaseType().getFullQualifiedName().toString())#{else}Serializable#end {
+public interface $utility.capitalize($complexType.Name) 
+    extends #if($complexType.getBaseType())$utility.getJavaType($complexType.getBaseType().getFullQualifiedName().toString())#{else}Serializable#end {
 
+#set( $complexProps = [] )
 #foreach($propertyName in $complexType.PropertyNames)
     #set($property = $complexType.getProperty($propertyName))
 
@@ -42,7 +44,7 @@ public interface $utility.capitalize($complexType.Name) extends #if($complexType
     void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));
 
     #if($utility.isComplex($property.Type.FullQualifiedName))#*
-      *#$utility.getJavaType($property.Type) new$utility.capitalize($property.Name)();
+      *##set( $adding = $complexProps.add($property) )
     #end
 
 #end
@@ -62,3 +64,20 @@ public interface $utility.capitalize($complexType.Name) extends #if($complexType
     void set$utility.capitalize($property.Name)(final $utility.getJavaType($type, $property.Collection) _$utility.uncapitalize($property.Name));
 
 #end
+
+#if( $complexProps.size() > 0 )
+    #if( $complexType.baseType )
+    @Override
+    #end
+    ComplexFactory factory();
+
+    interface ComplexFactory #if( $complexType.baseType )
+           extends ${utility.getJavaType($complexType.getBaseType())}.ComplexFactory#end{
+    #foreach($property in $complexProps)
+         @Property(name = "$property.Name",
+                   type = "$property.Type.FullQualifiedName.toString()")
+         $utility.getJavaType($property.Type) new$utility.capitalize($property.Name)();
+
+    #end
+    }
+#end

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
index 05ec9f1..bdaaf0e 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -233,31 +233,36 @@ public abstract class AbstractServices {
     final Response res;
 
     if (matcher.find()) {
-      String method = matcher.group(1);
-      if ("PATCH".equals(method) || "MERGE".equals(method)) {
-        headers.putSingle("X-HTTP-METHOD", method);
-        method = "POST";
-      }
-
       final String url = matcher.group(2);
-
       final WebClient client = WebClient.create(url);
       client.headers(headers);
-      res = client.invoke(method, body.getDataHandler().getInputStream());
-      client.close();
-    } else if (matcherRef.find()) {
-      String method = matcherRef.group(1);
-      if ("PATCH".equals(method) || "MERGE".equals(method)) {
-        headers.putSingle("X-HTTP-METHOD", method);
-        method = "POST";
+
+      final String method = matcher.group(1);
+      if ("DELETE".equals(method)) {
+        res = client.delete();
+      } else if ("PATCH".equals(method) || "MERGE".equals(method)) {
+        client.header("X-HTTP-METHOD", method);
+        res = client.invoke("POST", body.getDataHandler().getInputStream());
+      } else {
+        res = client.invoke(method, body.getDataHandler().getInputStream());
       }
 
+      client.close();
+    } else if (matcherRef.find()) {
       final String url = matcherRef.group(2);
-
       final WebClient client = WebClient.create(references.get(url));
       client.headers(headers);
 
-      res = client.invoke(method, body.getDataHandler().getInputStream());
+      String method = matcherRef.group(1);
+      if ("DELETE".equals(method)) {
+        res = client.delete();
+      } else if ("PATCH".equals(method) || "MERGE".equals(method)) {
+        client.header("X-HTTP-METHOD", method);
+        res = client.invoke("POST", body.getDataHandler().getInputStream());
+      } else {
+        res = client.invoke(method, body.getDataHandler().getInputStream());
+      }
+
       client.close();
     } else {
       res = null;
@@ -406,7 +411,7 @@ public abstract class AbstractServices {
       } else {
         final ResWrap<JSONEntityImpl> jcont = mapper.readValue(IOUtils.toInputStream(changes, Constants.ENCODING),
                 new TypeReference<JSONEntityImpl>() {
-                });
+        });
 
         entryChanges = dataBinder.toAtomEntity(jcont.getPayload());
       }
@@ -593,8 +598,8 @@ public abstract class AbstractServices {
         } else {
           final ResWrap<JSONEntityImpl> jcontainer =
                   mapper.readValue(IOUtils.toInputStream(entity, Constants.ENCODING),
-                          new TypeReference<JSONEntityImpl>() {
-                          });
+                  new TypeReference<JSONEntityImpl>() {
+          });
 
           entry = dataBinder.toAtomEntity(jcontainer.getPayload());
 
@@ -621,7 +626,7 @@ public abstract class AbstractServices {
       ResWrap<AtomEntityImpl> result = atomDeserializer.read(serialization, AtomEntityImpl.class);
       result = new ResWrap<AtomEntityImpl>(
               URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX)
-                      + entitySetName + Constants.get(version, ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
+              + entitySetName + Constants.get(version, ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
               null, result.getPayload());
 
       final String path = Commons.getEntityBasePath(entitySetName, entityKey);
@@ -684,13 +689,13 @@ public abstract class AbstractServices {
               replaceAll("\"Salary\":[0-9]*,", "\"Salary\":0,").
               replaceAll("\"Title\":\".*\"", "\"Title\":\"[Sacked]\"").
               replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>.*\\</d:Salary\\>",
-                      "<d:Salary m:type=\"Edm.Int32\">0</d:Salary>").
+              "<d:Salary m:type=\"Edm.Int32\">0</d:Salary>").
               replaceAll("\\<d:Title\\>.*\\</d:Title\\>", "<d:Title>[Sacked]</d:Title>");
 
       final FSManager fsManager = FSManager.instance(version);
       fsManager.putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
               fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(version,
-                              ConstantKey.ENTITY), utils.getKey()));
+              ConstantKey.ENTITY), utils.getKey()));
 
       return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
     } catch (Exception e) {
@@ -742,9 +747,9 @@ public abstract class AbstractServices {
         final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
         newContent = newContent.
                 replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
-                        "\"Salary\":" + newSalary + ",").
+                "\"Salary\":" + newSalary + ",").
                 replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
-                        "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
+                "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
       }
 
       FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
@@ -893,7 +898,7 @@ public abstract class AbstractServices {
         } else {
           mapper.writeValue(
                   writer, new JSONFeedContainer(container.getContextURL(), container.getMetadataETag(),
-                          dataBinder.toJSONEntitySet(container.getPayload())));
+                  dataBinder.toJSONEntitySet(container.getPayload())));
         }
 
         return xml.createResponse(
@@ -1556,8 +1561,8 @@ public abstract class AbstractServices {
               mapper.writeValue(
                       writer,
                       new JSONFeedContainer(container.getContextURL(),
-                              container.getMetadataETag(),
-                              dataBinder.toJSONEntitySet((AtomEntitySetImpl) container.getPayload())));
+                      container.getMetadataETag(),
+                      dataBinder.toJSONEntitySet((AtomEntitySetImpl) container.getPayload())));
             }
           } else {
             final ResWrap<Entity> container =
@@ -1570,8 +1575,8 @@ public abstract class AbstractServices {
               mapper.writeValue(
                       writer,
                       new JSONEntryContainer(container.getContextURL(),
-                              container.getMetadataETag(),
-                              dataBinder.toJSONEntity((AtomEntityImpl) container.getPayload())));
+                      container.getMetadataETag(),
+                      dataBinder.toJSONEntity((AtomEntityImpl) container.getPayload())));
             }
           }
 
@@ -1641,9 +1646,9 @@ public abstract class AbstractServices {
 
     final ResWrap<AtomPropertyImpl> container = new ResWrap<AtomPropertyImpl>(
             URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX)
-                    + (version.compareTo(ODataServiceVersion.V40) >= 0
-                    ? entitySetName + "(" + entityId + ")/" + path
-                    : property.getType())),
+            + (version.compareTo(ODataServiceVersion.V40) >= 0
+            ? entitySetName + "(" + entityId + ")/" + path
+            : property.getType())),
             entryContainer.getMetadataETag(),
             property);
 
@@ -1651,9 +1656,9 @@ public abstract class AbstractServices {
             null,
             searchForValue
             ? IOUtils.toInputStream(
-                    container.getPayload().getValue() == null || container.getPayload().getValue().isNull()
-                    ? StringUtils.EMPTY
-                    : container.getPayload().getValue().asPrimitive().get(), Constants.ENCODING)
+            container.getPayload().getValue() == null || container.getPayload().getValue().isNull()
+            ? StringUtils.EMPTY
+            : container.getPayload().getValue().asPrimitive().get(), Constants.ENCODING)
             : utils.writeProperty(acceptType, container),
             Commons.getETag(Commons.getEntityBasePath(entitySetName, entityId), version),
             acceptType);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
index b7f2fd6..5f8a345 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
@@ -553,7 +553,7 @@ public abstract class AbstractUtilities {
     } else {
       final ResWrap<JSONEntitySetImpl> container =
               mapper.readValue(entitySet, new TypeReference<JSONEntitySetImpl>() {
-              });
+      });
       entry = dataBinder.toAtomEntitySet(container.getPayload());
     }
 
@@ -571,7 +571,7 @@ public abstract class AbstractUtilities {
     } else {
       mapper.writeValue(
               writer, new JSONFeedContainer(container.getContextURL(),
-                      container.getMetadataETag(), dataBinder.toJSONEntitySet(container.getPayload())));
+              container.getMetadataETag(), dataBinder.toJSONEntitySet(container.getPayload())));
     }
 
     return IOUtils.toInputStream(writer.toString(), Constants.ENCODING);
@@ -586,7 +586,7 @@ public abstract class AbstractUtilities {
     } else {
       final ResWrap<JSONEntityImpl> jcontainer =
               mapper.readValue(entity, new TypeReference<JSONEntityImpl>() {
-              });
+      });
       container = new ResWrap<AtomEntityImpl>(
               jcontainer.getContextURL(),
               jcontainer.getMetadataETag(),
@@ -611,7 +611,7 @@ public abstract class AbstractUtilities {
     } else {
       mapper.writeValue(
               writer, new JSONEntryContainer(container.getContextURL(), container.getMetadataETag(),
-                      dataBinder.toJSONEntity(container.getPayload())));
+              dataBinder.toJSONEntity(container.getPayload())));
     }
 
     return IOUtils.toInputStream(writer.toString(), Constants.ENCODING);
@@ -641,7 +641,7 @@ public abstract class AbstractUtilities {
     } else {
       final ResWrap<JSONPropertyImpl> jcontainer = mapper.readValue(property,
               new TypeReference<JSONPropertyImpl>() {
-              });
+      });
 
       atomProperty = dataBinder.toAtomProperty(jcontainer.getPayload(), entryType);
     }
@@ -658,7 +658,7 @@ public abstract class AbstractUtilities {
     } else {
       mapper.writeValue(
               writer, new JSONPropertyContainer(container.getContextURL(), container.getMetadataETag(),
-                      dataBinder.toJSONProperty(container.getPayload())));
+              dataBinder.toJSONProperty(container.getPayload())));
     }
 
     return IOUtils.toInputStream(writer.toString(), Constants.ENCODING);
@@ -691,14 +691,14 @@ public abstract class AbstractUtilities {
         if (entity.getProperty("MessageId") == null || entity.getProperty("FromUsername") == null) {
           if (Commons.SEQUENCE.containsKey(entitySetName)) {
             messageId = Commons.SEQUENCE.get(entitySetName) + 1;
-            res = "MessageId=" + String.valueOf(messageId) + ",FromUsername=1";
+            res = "FromUsername=1" + ",MessageId=" + String.valueOf(messageId);
           } else {
             throw new Exception(String.format("Unable to retrieve entity key value for %s", entitySetName));
           }
         } else {
           messageId = Integer.valueOf(entity.getProperty("MessageId").getValue().asPrimitive().get());
-          res = "MessageId=" + entity.getProperty("MessageId").getValue().asPrimitive().get()
-                  + ",FromUsername=" + entity.getProperty("FromUsername").getValue().asPrimitive().get();
+          res = "FromUsername=" + entity.getProperty("FromUsername").getValue().asPrimitive().get()
+                  + ",MessageId=" + entity.getProperty("MessageId").getValue().asPrimitive().get();
         }
         Commons.SEQUENCE.put(entitySetName, messageId);
       } else if ("Order".equals(entitySetName)) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/fit/src/main/resources/V30/CustomerInfo/16/entity.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V30/CustomerInfo/16/entity.full.json b/fit/src/main/resources/V30/CustomerInfo/16/entity.full.json
new file mode 100644
index 0000000..4df06c0
--- /dev/null
+++ b/fit/src/main/resources/V30/CustomerInfo/16/entity.full.json
@@ -0,0 +1,11 @@
+{
+  "odata.metadata": "http://localhost:8080/DefaultService.svc/$metadata#CustomerInfo/@Element",
+  "odata.type": "Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo",
+  "odata.id": "http://localhost:8080/DefaultService.svc/CustomerInfo(16)",
+  "odata.editLink": "CustomerInfo(16)",
+  "odata.mediaEditLink": "CustomerInfo(16)/$value",
+  "odata.mediaReadLink": "CustomerInfo(16)/$value",
+  "odata.mediaContentType": "*/*",
+  "CustomerInfoId": 16,
+  "Information": "uuvoqobtxfgtnzugqjsocbhjkynsjafonxuxmcrnyldkxvpnuezalvpyhjpsmkgxacuruxtjruusxylndzxgefpscvk"
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/fit/src/main/resources/V30/CustomerInfo/16/entity.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V30/CustomerInfo/16/entity.xml b/fit/src/main/resources/V30/CustomerInfo/16/entity.xml
new file mode 100644
index 0000000..38f4fed
--- /dev/null
+++ b/fit/src/main/resources/V30/CustomerInfo/16/entity.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    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.
+
+-->
+<entry xml:base="http://localhost:8080/DefaultService.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
+  <id>http://localhost:8080/DefaultService.svc/CustomerInfo(16)</id>
+  <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.CustomerInfo" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link rel="edit" title="CustomerInfo" href="CustomerInfo(16)" />
+  <title />
+  <updated>2014-05-11T15:46:20Z</updated>
+  <author>
+    <name />
+  </author>
+  <link rel="edit-media" title="CustomerInfo" href="CustomerInfo(16)/$value" />
+  <content type="*/*" src="CustomerInfo(16)/$value" />
+  <m:properties>
+    <d:CustomerInfoId m:type="Edm.Int32">16</d:CustomerInfoId>
+    <d:Information>uuvoqobtxfgtnzugqjsocbhjkynsjafonxuxmcrnyldkxvpnuezalvpyhjpsmkgxacuruxtjruusxylndzxgefpscvk</d:Information>
+  </m:properties>
+</entry>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTest.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTest.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTest.java
index a3dfd33..fbee685 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTest.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTest.java
@@ -30,11 +30,14 @@ import org.apache.olingo.ext.proxy.EntityContainerFactory;
 import org.apache.olingo.ext.proxy.context.EntityContext;
 import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
         DefaultContainer;
-import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.
-        ContactDetails;
-import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Customer;
-import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Aliases;
-import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Phone;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.ContactDetails;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.Customer;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.Aliases;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.Phone;
 
 import org.junit.BeforeClass;
 import org.slf4j.Logger;
@@ -94,18 +97,21 @@ public abstract class AbstractTest {
     // add key attribute
     customer.setCustomerId(id);
 
-    final ContactDetails cd = customer.newPrimaryContactInfo();
+    final ContactDetails cd = customer.factory().newPrimaryContactInfo();
     cd.setAlternativeNames(Arrays.asList("alternative1", "alternative2"));
     cd.setEmailBag(Collections.<String>singleton("myname@mydomain.org"));
     cd.setMobilePhoneBag(Collections.<Phone>emptySet());
+    customer.setPrimaryContactInfo(cd);
 
-    final Aliases aliases = cd.newContactAlias();
+    final Aliases aliases = cd.factory().newContactAlias();
     aliases.setAlternativeNames(Collections.<String>singleton("myAlternativeName"));
+    cd.setContactAlias(aliases);
 
-    final ContactDetails bcd = customer.newBackupContactInfo();
+    final ContactDetails bcd = customer.factory().newBackupContactInfo();
     bcd.setAlternativeNames(Arrays.asList("alternative3", "alternative4"));
     bcd.setEmailBag(Collections.<String>emptySet());
     bcd.setMobilePhoneBag(Collections.<Phone>emptySet());
+    customer.setBackupContactInfo(Collections.<ContactDetails>singleton(bcd));
 
     return customer;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f1cbc4af/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java
new file mode 100644
index 0000000..3ef2691
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java
@@ -0,0 +1,210 @@
+/*
+ * 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.proxy.v3;
+
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.Customer;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.Employee;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.Message;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.MessageKey;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.Order;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.
+        types.OrderCollection;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Ignore;
+
+import org.junit.Test;
+
+/**
+ * This is the unit test class to check entity create operations.
+ */
+public class EntityCreateTestITCase extends AbstractTest {
+
+    @Test
+    @Ignore
+    public void create() {
+        final String sampleName = "sample customer from proxy";
+        final Integer id = 100;
+
+        getSampleCustomerProfile(id, sampleName, container);
+        container.flush();
+
+        Customer actual = readCustomer(container, id);
+        checkSampleCustomerProfile(actual, id, sampleName);
+
+        container.getCustomer().delete(actual.getCustomerId());
+        actual = container.getCustomer().get(id);
+        assertNull(actual);
+
+        entityContext.detachAll();
+        actual = container.getCustomer().get(id);
+        assertNotNull(actual);
+
+        container.getCustomer().delete(actual.getCustomerId());
+        container.flush();
+
+        actual = container.getCustomer().get(id);
+        assertNull(actual);
+
+        entityContext.detachAll();
+        actual = container.getCustomer().get(id);
+        assertNull(actual);
+    }
+
+    @Test
+    @Ignore
+    public void createEmployee() {
+        final Integer id = 101;
+
+        final Employee employee = container.getPerson().newEmployee();
+        employee.setPersonId(id);
+        employee.setName("sample employee from proxy");
+        employee.setManagersPersonId(-9918);
+        employee.setSalary(2147483647);
+        employee.setTitle("CEO");
+
+        container.flush();
+
+        Employee actual = container.getPerson().get(id, Employee.class);
+        assertNotNull(actual);
+        assertEquals(id, actual.getPersonId());
+
+        entityContext.detachAll();
+        actual = container.getPerson().get(id, Employee.class);
+        assertNotNull(actual);
+
+        container.getPerson().delete(actual.getPersonId());
+        container.flush();
+
+        actual = container.getPerson().get(id, Employee.class);
+        assertNull(actual);
+
+        entityContext.detachAll();
+        actual = container.getPerson().get(id, Employee.class);
+        assertNull(actual);
+    }
+
+    @Test
+    @Ignore
+    public void createWithNavigation() {
+        final String sampleName = "sample customer from proxy with navigation";
+        final Integer id = 101;
+
+        final Customer original = getSampleCustomerProfile(id, sampleName, container);
+        original.setInfo(container.getCustomerInfo().get(16));
+        container.flush();
+
+        Customer actual = readCustomer(container, id);
+        checkSampleCustomerProfile(actual, id, sampleName);
+        assertEquals(Integer.valueOf(16), actual.getInfo().getCustomerInfoId());
+
+        container.getCustomer().delete(actual.getCustomerId());
+        container.flush();
+
+        actual = container.getCustomer().get(id);
+        assertNull(actual);
+    }
+
+    @Test
+    @Ignore
+    public void createWithBackNavigation() {
+        final String sampleName = "sample customer from proxy with back navigation";
+        final Integer id = 102;
+
+        Order order = container.getOrder().newOrder();
+        order.setCustomerId(id);
+        order.setOrderId(id); // same id ...
+
+        final Customer customer = getSampleCustomerProfile(id, sampleName, container);
+
+        final OrderCollection orders = container.getOrder().newOrderCollection();
+        orders.add(order);
+
+        customer.setOrders(orders);
+        order.setCustomer(customer);
+        container.flush();
+
+        assertEquals(id, order.getOrderId());
+        assertEquals(id, order.getCustomerId());
+
+        Customer actual = readCustomer(container, id);
+        checkSampleCustomerProfile(actual, id, sampleName);
+
+        assertEquals(1, actual.getOrders().size());
+        assertEquals(id, actual.getOrders().iterator().next().getOrderId());
+        assertEquals(id, actual.getOrders().iterator().next().getCustomerId());
+
+        order = container.getOrder().get(id);
+        assertNotNull(order);
+        assertEquals(id, order.getCustomer().getCustomerId());
+
+        container.getOrder().delete(actual.getOrders());
+        container.flush();
+
+        order = container.getOrder().get(id);
+        assertNull(order);
+
+        actual = readCustomer(container, id);
+        assertTrue(actual.getOrders().isEmpty());
+
+        container.getCustomer().delete(actual.getCustomerId());
+        container.flush();
+
+        actual = container.getCustomer().get(id);
+        assertNull(actual);
+    }
+
+    @Test
+    @Ignore
+    public void multiKey() {
+        Message message = container.getMessage().newMessage();
+        message.setMessageId(100);
+        message.setFromUsername("fromusername");
+        message.setToUsername("myusername");
+        message.setIsRead(false);
+        message.setSubject("test message");
+        message.setBody("test");
+
+        container.flush();
+
+        MessageKey key = new MessageKey();
+        key.setFromUsername("fromusername");
+        key.setMessageId(100);
+
+        message = container.getMessage().get(key);
+        assertNotNull(message);
+        assertEquals(Integer.valueOf(100), message.getMessageId());
+        assertEquals("fromusername", message.getFromUsername());
+        assertEquals("myusername", message.getToUsername());
+        assertEquals("test message", message.getSubject());
+        assertEquals("test", message.getBody());
+
+        container.getMessage().delete(key);
+        container.flush();
+
+        assertNull(container.getMessage().get(key));
+    }
+}


Mime
View raw message