You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2013/07/26 13:22:50 UTC

[45/51] [partial] initial commit

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmNameBuilder.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmNameBuilder.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmNameBuilder.java
new file mode 100644
index 0000000..271455d
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmNameBuilder.java
@@ -0,0 +1,545 @@
+/*******************************************************************************
+ * 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.odata2.processor.core.jpa.access.model;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+
+import javax.persistence.Column;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.PluralAttribute;
+
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.Mapping;
+import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmMappingModelAccess;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationEndView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationSetView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmBaseView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmComplexPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityContainerView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntitySetView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmMapping;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmNavigationPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.model.JPAEdmComplexType;
+import org.apache.olingo.odata2.processor.core.jpa.model.JPAEdmMappingImpl;
+
+public class JPAEdmNameBuilder {
+  private static final String ENTITY_CONTAINER_SUFFIX = "Container";
+  private static final String ENTITY_SET_SUFFIX = "s";
+  private static final String ASSOCIATIONSET_SUFFIX = "Set";
+  private static final String NAVIGATION_NAME = "Details";
+  private static final String UNDERSCORE = "_";
+
+  public static FullQualifiedName build(final JPAEdmBaseView view, final String name) {
+    FullQualifiedName fqName = new FullQualifiedName(buildNamespace(view),
+        name);
+    return fqName;
+  }
+
+  /*
+   * ************************************************************************
+   * EDM EntityType Name - RULES
+   * ************************************************************************
+   * EDM Entity Type Name = JPA Entity Name EDM Entity Type Internal Name =
+   * JPA Entity Name
+   * ************************************************************************
+   * EDM Entity Type Name - RULES
+   * ************************************************************************
+   */
+  public static void build(final JPAEdmEntityTypeView view) {
+
+    EntityType edmEntityType = view.getEdmEntityType();
+    String jpaEntityName = view.getJPAEntityType().getName();
+    JPAEdmMappingModelAccess mappingModelAccess = view
+        .getJPAEdmMappingModelAccess();
+    String edmEntityTypeName = null;
+    if (mappingModelAccess != null
+        && mappingModelAccess.isMappingModelExists()) {
+      edmEntityTypeName = mappingModelAccess
+          .mapJPAEntityType(jpaEntityName);
+    }
+
+    JPAEdmMapping mapping = new JPAEdmMappingImpl();
+    mapping.setJPAType(view.getJPAEntityType().getJavaType());
+
+    if (edmEntityTypeName == null) {
+      edmEntityTypeName = jpaEntityName;
+    }
+    //Setting the mapping object
+    edmEntityType.setMapping(((Mapping) mapping)
+        .setInternalName(jpaEntityName));
+
+    edmEntityType.setName(edmEntityTypeName);
+
+  }
+
+  /*
+   * ************************************************************************
+   * EDM Schema Name - RULES
+   * ************************************************************************
+   * Java Persistence Unit name is set as Schema's Namespace
+   * ************************************************************************
+   * EDM Schema Name - RULES
+   * ************************************************************************
+   */
+  public static void build(final JPAEdmSchemaView view)
+      throws ODataJPAModelException {
+    view.getEdmSchema().setNamespace(buildNamespace(view));
+  }
+
+  /*
+   * ************************************************************************
+   * EDM Property Name - RULES
+   * ************************************************************************
+   * OData Property Names are represented in Camel Case. The first character
+   * of JPA Attribute Name is converted to an UpperCase Character and set as
+   * OData Property Name. JPA Attribute Name is set as Internal Name for OData
+   * Property. The Column name (annotated as @Column(name="x")) is set as
+   * column name in the mapping object.
+   * ************************************************************************
+   * EDM Property Name - RULES
+   * ************************************************************************
+   */
+  public static void build(final JPAEdmPropertyView view, final boolean isComplexMode) {
+    Attribute<?, ?> jpaAttribute = view.getJPAAttribute();
+    String jpaAttributeName = jpaAttribute.getName();
+    String propertyName = null;
+
+    JPAEdmMappingModelAccess mappingModelAccess = view
+        .getJPAEdmMappingModelAccess();
+    if (mappingModelAccess != null
+        && mappingModelAccess.isMappingModelExists()) {
+      if (isComplexMode) {
+        propertyName = mappingModelAccess
+            .mapJPAEmbeddableTypeAttribute(view
+                .getJPAEdmComplexTypeView()
+                .getJPAEmbeddableType().getJavaType()
+                .getSimpleName(), jpaAttributeName);
+      } else {
+        propertyName = mappingModelAccess.mapJPAAttribute(
+            view.getJPAEdmEntityTypeView().getJPAEntityType()
+                .getName(), jpaAttributeName);
+      }
+    }
+    if (propertyName == null) {
+      propertyName = Character.toUpperCase(jpaAttributeName.charAt(0))
+          + jpaAttributeName.substring(1);
+    }
+
+    view.getEdmSimpleProperty().setName(propertyName);
+
+    JPAEdmMapping mapping = new JPAEdmMappingImpl();
+    ((Mapping) mapping).setInternalName(jpaAttributeName);
+
+    AnnotatedElement annotatedElement = (AnnotatedElement) jpaAttribute
+        .getJavaMember();
+    if (annotatedElement != null) {
+      Column column = annotatedElement.getAnnotation(Column.class);
+      if (column != null) {
+        mapping.setJPAColumnName(column.name());
+      }
+    } else {
+      ManagedType<?> managedType = jpaAttribute.getDeclaringType();
+      if (managedType != null) {
+        Class<?> clazz = managedType.getJavaType();
+        try {
+          Field field = clazz.getDeclaredField(jpaAttributeName);
+          Column column = field.getAnnotation(Column.class);
+          if (column != null) {
+            mapping.setJPAColumnName(column.name());
+          }
+        } catch (SecurityException e) {
+
+        } catch (NoSuchFieldException e) {
+
+        }
+      }
+
+    }
+    view.getEdmSimpleProperty().setMapping((Mapping) mapping);
+  }
+
+  /*
+   * ************************************************************************
+   * EDM EntityContainer Name - RULES
+   * ************************************************************************
+   * Entity Container Name = EDM Namespace + Literal "Container"
+   * ************************************************************************
+   * EDM EntityContainer Name - RULES
+   * ************************************************************************
+   */
+  public static void build(final JPAEdmEntityContainerView view) {
+    view.getEdmEntityContainer().setName(
+        buildNamespace(view) + ENTITY_CONTAINER_SUFFIX);
+  }
+
+  /*
+   * ************************************************************************
+   * EDM EntitySet Name - RULES
+   * ************************************************************************
+   * Entity Set Name = JPA Entity Type Name + Literal "s"
+   * ************************************************************************
+   * EDM EntitySet Name - RULES
+   * ************************************************************************
+   */
+  public static void build(final JPAEdmEntitySetView view,
+      final JPAEdmEntityTypeView entityTypeView) {
+    FullQualifiedName fQname = view.getEdmEntitySet().getEntityType();
+    JPAEdmMappingModelAccess mappingModelAccess = view
+        .getJPAEdmMappingModelAccess();
+    String entitySetName = null;
+    if (mappingModelAccess != null
+        && mappingModelAccess.isMappingModelExists()) {
+      Mapping mapping = entityTypeView.getEdmEntityType().getMapping();
+      if (mapping != null) {
+        entitySetName = mappingModelAccess.mapJPAEntitySet(mapping
+            .getInternalName());
+      }
+    }
+
+    if (entitySetName == null) {
+      entitySetName = fQname.getName() + ENTITY_SET_SUFFIX;
+    }
+
+    view.getEdmEntitySet().setName(entitySetName);
+  }
+
+  /*
+   * ************************************************************************
+   * EDM Complex Type Name - RULES
+   * ************************************************************************
+   * Complex Type Name = JPA Embeddable Type Simple Name.
+   * ************************************************************************
+   * EDM Complex Type Name - RULES
+   * ************************************************************************
+   */
+  public static void build(final JPAEdmComplexType view) {
+
+    JPAEdmMappingModelAccess mappingModelAccess = view
+        .getJPAEdmMappingModelAccess();
+    String jpaEmbeddableTypeName = view.getJPAEmbeddableType()
+        .getJavaType().getSimpleName();
+    String edmComplexTypeName = null;
+    if (mappingModelAccess != null
+        && mappingModelAccess.isMappingModelExists()) {
+      edmComplexTypeName = mappingModelAccess
+          .mapJPAEmbeddableType(jpaEmbeddableTypeName);
+    }
+
+    if (edmComplexTypeName == null) {
+      edmComplexTypeName = jpaEmbeddableTypeName;
+    }
+
+    view.getEdmComplexType().setName(edmComplexTypeName);
+
+  }
+
+  /*
+   * ************************************************************************
+   * EDM Complex Property Name - RULES
+   * ************************************************************************
+   * The first character of JPA complex attribute name is converted to
+   * uppercase. The modified JPA complex attribute name is assigned as EDM
+   * complex property name. The unmodified JPA complex attribute name is
+   * assigned as internal name.
+   * ************************************************************************
+   * EDM Complex Property Name - RULES
+   * ************************************************************************
+   */
+  public static void build(final JPAEdmComplexPropertyView complexView,
+      final JPAEdmPropertyView propertyView) {
+
+    ComplexProperty complexProperty = complexView.getEdmComplexProperty();
+
+    String jpaAttributeName = propertyView.getJPAAttribute().getName();
+    String jpaEntityTypeName = propertyView.getJPAEdmEntityTypeView()
+        .getJPAEntityType().getName();
+
+    JPAEdmMappingModelAccess mappingModelAccess = complexView
+        .getJPAEdmMappingModelAccess();
+    String propertyName = null;
+
+    if (mappingModelAccess != null
+        && mappingModelAccess.isMappingModelExists()) {
+      propertyName = mappingModelAccess.mapJPAAttribute(
+          jpaEntityTypeName, jpaAttributeName);
+    }
+
+    if (propertyName == null) {
+      propertyName = Character.toUpperCase(jpaAttributeName.charAt(0))
+          + jpaAttributeName.substring(1);
+    }
+    // change for navigation property issue
+    JPAEdmMapping mapping = new JPAEdmMappingImpl();
+    ((Mapping) mapping).setInternalName(jpaAttributeName);
+    mapping.setJPAType(propertyView.getJPAAttribute().getJavaType());
+    complexProperty.setMapping((Mapping) mapping);
+
+    complexProperty.setName(propertyName);
+
+  }
+
+  public static void build(final JPAEdmComplexPropertyView complexView, final String parentComplexTypeName)
+  {
+    ComplexProperty complexProperty = complexView.getEdmComplexProperty();
+
+    JPAEdmMappingModelAccess mappingModelAccess = complexView.getJPAEdmMappingModelAccess();
+    JPAEdmPropertyView propertyView = ((JPAEdmPropertyView) complexView);
+    String jpaAttributeName = propertyView.getJPAAttribute().getName();
+    String propertyName = null;
+    if (mappingModelAccess != null
+        && mappingModelAccess.isMappingModelExists()) {
+      propertyName = mappingModelAccess.mapJPAEmbeddableTypeAttribute(
+          parentComplexTypeName, jpaAttributeName);
+    }
+    if (propertyName == null) {
+      propertyName = Character.toUpperCase(jpaAttributeName.charAt(0))
+          + jpaAttributeName.substring(1);
+    }
+    JPAEdmMapping mapping = new JPAEdmMappingImpl();
+    ((Mapping) mapping).setInternalName(jpaAttributeName);
+    mapping.setJPAType(propertyView.getJPAAttribute().getJavaType());
+    complexProperty.setMapping((Mapping) mapping);
+    complexProperty.setName(propertyName);
+
+  }
+
+  /*
+   * ************************************************************************
+   * EDM Association End Name - RULES
+   * ************************************************************************
+   * Association End name = Namespace + Entity Type Name
+   * ************************************************************************
+   * EDM Association End Name - RULES
+   * ************************************************************************
+   */
+  public static void build(final JPAEdmAssociationEndView assocaitionEndView,
+      final JPAEdmEntityTypeView entityTypeView, final JPAEdmPropertyView propertyView) {
+
+    String namespace = buildNamespace(assocaitionEndView);
+
+    String name = entityTypeView.getEdmEntityType().getName();
+    FullQualifiedName fQName = new FullQualifiedName(namespace, name);
+    assocaitionEndView.getEdmAssociationEnd1().setType(fQName);
+
+    name = null;
+    String jpaEntityTypeName = null;
+    try {
+
+      PluralAttribute<?, ?, ?> jpattr = (PluralAttribute<?, ?, ?>) propertyView
+          .getJPAAttribute();
+
+      jpaEntityTypeName = jpattr.getElementType().getJavaType()
+          .getSimpleName();
+
+    } catch (Exception e) {
+      jpaEntityTypeName = propertyView.getJPAAttribute().getJavaType()
+          .getSimpleName();
+    }
+
+    JPAEdmMappingModelAccess mappingModelAccess = assocaitionEndView
+        .getJPAEdmMappingModelAccess();
+
+    if (mappingModelAccess != null
+        && mappingModelAccess.isMappingModelExists()) {
+      name = mappingModelAccess.mapJPAEntityType(jpaEntityTypeName);
+    }
+
+    if (name == null) {
+      name = jpaEntityTypeName;
+    }
+
+    fQName = new FullQualifiedName(namespace, name);
+    assocaitionEndView.getEdmAssociationEnd2().setType(fQName);
+
+  }
+
+  private static String buildNamespace(final JPAEdmBaseView view) {
+    JPAEdmMappingModelAccess mappingModelAccess = view
+        .getJPAEdmMappingModelAccess();
+    String namespace = null;
+    if (mappingModelAccess != null
+        && mappingModelAccess.isMappingModelExists()) {
+      namespace = mappingModelAccess.mapJPAPersistenceUnit(view
+          .getpUnitName());
+    }
+    if (namespace == null) {
+      namespace = view.getpUnitName();
+    }
+
+    return namespace;
+  }
+
+  /*
+   * ************************************************************************
+   * EDM Association Name - RULES
+   * ************************************************************************
+   * Association name = Association + End1 Name + End2 Name
+   * ************************************************************************
+   * EDM Association Name - RULES
+   * ************************************************************************
+   */
+
+  public static void build(final JPAEdmAssociationView view, final int count) {
+    Association association = view.getEdmAssociation();
+    String associationName = null;
+    String end1Name = association.getEnd1().getType().getName();
+    String end2Name = association.getEnd2().getType().getName();
+
+    if (end1Name.compareToIgnoreCase(end2Name) > 0) {
+      associationName = end2Name + UNDERSCORE + end1Name;
+    } else {
+      associationName = end1Name + UNDERSCORE + end2Name;
+    }
+    if (count > 1) {
+      associationName = associationName + Integer.toString(count - 1);
+    }
+    association.setName(associationName);
+
+  }
+
+  /*
+   * ************************************************************************
+   * EDM Association Set Name - RULES
+   * ************************************************************************
+   * Association Set name = Association Name + "Set"
+   * ************************************************************************
+   * EDM Association Set Name - RULES
+   * ************************************************************************
+   */
+  public static void build(final JPAEdmAssociationSetView view) {
+    AssociationSet associationSet = view.getEdmAssociationSet();
+
+    String name = view.getEdmAssociation().getName();
+    associationSet.setName(name + ASSOCIATIONSET_SUFFIX);
+
+  }
+
+  public static void build(final JPAEdmAssociationView associationView,
+      final JPAEdmPropertyView propertyView,
+      final JPAEdmNavigationPropertyView navPropertyView, final int count) {
+
+    String toName = null;
+    String fromName = null;
+    String navPropName = null;
+    NavigationProperty navProp = navPropertyView.getEdmNavigationProperty();
+    String namespace = buildNamespace(associationView);
+
+    Association association = associationView.getEdmAssociation();
+    navProp.setRelationship(new FullQualifiedName(namespace, association
+        .getName()));
+
+    FullQualifiedName associationEndTypeOne = association.getEnd1()
+        .getType();
+    FullQualifiedName associationEndTypeTwo = association.getEnd2()
+        .getType();
+
+    Attribute<?, ?> jpaAttribute = propertyView.getJPAAttribute();
+    navProp.setMapping(new Mapping().setInternalName(jpaAttribute.getName()));
+
+    String jpaEntityTypeName = propertyView.getJPAEdmEntityTypeView()
+        .getJPAEntityType().getName();
+    JPAEdmMappingModelAccess mappingModelAccess = navPropertyView
+        .getJPAEdmMappingModelAccess();
+
+    try {
+      PluralAttribute<?, ?, ?> jpattr = (PluralAttribute<?, ?, ?>) propertyView
+          .getJPAAttribute();
+
+      if (mappingModelAccess != null
+          && mappingModelAccess.isMappingModelExists()) {
+        toName = mappingModelAccess.mapJPAEntityType(jpattr
+            .getElementType().getJavaType().getSimpleName());
+        fromName = mappingModelAccess
+            .mapJPAEntityType(jpaEntityTypeName);
+        navPropName = mappingModelAccess.mapJPARelationship(
+            jpaEntityTypeName, jpattr.getName());
+      }
+      if (toName == null) {
+        toName = jpattr.getElementType().getJavaType().getSimpleName();
+      }
+      if (fromName == null) {
+        fromName = jpaEntityTypeName;
+      }
+
+      if (navPropName == null) {
+        navPropName = toName.concat(NAVIGATION_NAME);
+      }
+      if (count > 1) {
+        navPropName = navPropName + Integer.toString(count - 1);
+      }
+      navProp.setName(navPropName);
+
+      if (toName.equals(associationEndTypeOne.getName())) {
+        navProp.setFromRole(association.getEnd2().getRole());
+        navProp.setToRole(association.getEnd1().getRole());
+      } else if (toName.equals(associationEndTypeTwo.getName())) {
+        navProp.setToRole(association.getEnd2().getRole());
+        navProp.setFromRole(association.getEnd1().getRole());
+      }
+
+    } catch (Exception e) {
+      if (mappingModelAccess != null
+          && mappingModelAccess.isMappingModelExists()) {
+        navPropName = mappingModelAccess.mapJPARelationship(
+            jpaEntityTypeName, jpaAttribute.getName());
+        toName = mappingModelAccess.mapJPAEntityType(jpaAttribute
+            .getJavaType().getSimpleName());
+        fromName = mappingModelAccess
+            .mapJPAEntityType(jpaEntityTypeName);
+      }
+      if (toName == null) {
+        toName = jpaAttribute.getJavaType().getSimpleName();
+      }
+      if (fromName == null) {
+        fromName = jpaEntityTypeName;
+      }
+
+      if (navPropName == null) {
+        navPropName = toName.concat(NAVIGATION_NAME);
+      }
+      if (count > 1) {
+        navPropName = navPropName + Integer.toString(count - 1);
+      }
+      navProp.setName(navPropName);
+
+      if (toName.equals(associationEndTypeOne.getName())) {
+        navProp.setFromRole(association.getEnd2().getRole());
+        navProp.setToRole(association.getEnd1().getRole());
+      } else if (toName.equals(associationEndTypeTwo.getName())) {
+
+        navProp.setToRole(association.getEnd2().getRole());
+        navProp.setFromRole(association.getEnd1().getRole());
+      }
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPATypeConvertor.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPATypeConvertor.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPATypeConvertor.java
new file mode 100644
index 0000000..ae9eabc
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPATypeConvertor.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * 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.odata2.processor.core.jpa.access.model;
+
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.metamodel.Attribute;
+
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+
+/**
+ * This class holds utility methods for Type conversions between JPA and OData Types.
+ * 
+ * @author SAP AG
+ *
+ */
+public class JPATypeConvertor {
+
+  /**
+   * This utility method converts a given jpa Type to equivalent
+   * EdmSimpleTypeKind for maintaining compatibility between Java and OData
+   * Types.
+   * 
+   * @param jpaType
+   *            The JPA Type input.
+   * @return The corresponding EdmSimpleTypeKind.
+   * @throws ODataJPAModelException
+   * @throws ODataJPARuntimeException 
+   * 
+   * @see EdmSimpleTypeKind
+   */
+  public static EdmSimpleTypeKind convertToEdmSimpleType(final Class<?> jpaType, final Attribute<?, ?> currentAttribute) throws ODataJPAModelException {
+    if (jpaType.equals(String.class)) {
+      return EdmSimpleTypeKind.String;
+    }
+    else if (jpaType.equals(Long.class) || jpaType.equals(long.class)) {
+      return EdmSimpleTypeKind.Int64;
+    }
+    else if (jpaType.equals(Short.class) || jpaType.equals(short.class)) {
+      return EdmSimpleTypeKind.Int16;
+    }
+    else if (jpaType.equals(Integer.class) || jpaType.equals(int.class)) {
+      return EdmSimpleTypeKind.Int32;
+    }
+    else if (jpaType.equals(Double.class) || jpaType.equals(double.class)) {
+      return EdmSimpleTypeKind.Double;
+    }
+    else if (jpaType.equals(Float.class) || jpaType.equals(float.class)) {
+      return EdmSimpleTypeKind.Single;
+    }
+    else if (jpaType.equals(BigDecimal.class)) {
+      return EdmSimpleTypeKind.Decimal;
+    }
+    else if (jpaType.equals(byte[].class)) {
+      return EdmSimpleTypeKind.Binary;
+    }
+    else if (jpaType.equals(Byte.class) || jpaType.equals(byte.class)) {
+      return EdmSimpleTypeKind.Byte;
+    }
+    else if (jpaType.equals(Byte[].class)) {
+      return EdmSimpleTypeKind.Binary;
+    }
+    else if (jpaType.equals(Boolean.class) || jpaType.equals(boolean.class)) {
+      return EdmSimpleTypeKind.Boolean;
+    }
+    else if ((jpaType.equals(Date.class)) || (jpaType.equals(Calendar.class))) {
+      try {
+        if ((currentAttribute != null) && (currentAttribute.getDeclaringType().getJavaType().getDeclaredField(currentAttribute.getName()).getAnnotation(Temporal.class).value() == TemporalType.TIME)) {
+          return EdmSimpleTypeKind.Time;
+        } else {
+          return EdmSimpleTypeKind.DateTime;
+        }
+      } catch (NoSuchFieldException e) {
+        throw ODataJPAModelException
+            .throwException(ODataJPAModelException.GENERAL.addContent(e.getMessage()), e);
+      } catch (SecurityException e) {
+        throw ODataJPAModelException
+            .throwException(ODataJPAModelException.GENERAL.addContent(e.getMessage()), e);
+      }
+    }
+    else if (jpaType.equals(UUID.class)) {
+      return EdmSimpleTypeKind.Guid;
+    }
+    throw ODataJPAModelException.throwException(ODataJPAModelException.TYPE_NOT_SUPPORTED.addContent(jpaType.toString()), null);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPACreateRequest.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPACreateRequest.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPACreateRequest.java
new file mode 100644
index 0000000..6297f67
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPACreateRequest.java
@@ -0,0 +1,477 @@
+/*******************************************************************************
+ * 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.odata2.processor.core.jpa.cud;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.Metamodel;
+
+import org.apache.olingo.odata2.api.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+
+public class JPACreateRequest extends JPAWriteRequest {
+
+  private Metamodel metamodel;
+
+  public JPACreateRequest() {
+    super();
+    jpaEmbeddableKeyMap = new HashMap<String, HashMap<String, String>>();
+    jpaEmbeddableKeyObjectMap = new HashMap<String, Class<?>>();
+  }
+
+  public JPACreateRequest(final Metamodel metamodel) {
+    this();
+    this.metamodel = metamodel;
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T> List<T> process(final PostUriInfo postUriInfo, final InputStream content, final String requestContentType) throws ODataJPARuntimeException {
+    final EdmEntitySet entitySet = postUriInfo.getTargetEntitySet();
+    EdmEntityType entityType = null;
+    try {
+      entityType = entitySet.getEntityType();
+    } catch (EdmException e3) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e3.getMessage()), e3);
+    }
+    String entityName = null;
+    try {
+      if (entityType.getMapping() != null && entityType.getMapping().getInternalName() != null)
+      {
+        entityName = entityType.getMapping().getInternalName();
+      } else {
+        entityName = entityType.getName();
+      }
+    } catch (EdmException e1) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e1.getMessage()), e1);
+    }
+    Object jpaEntity = null;
+    Set<EntityType<?>> entityTypeSet = metamodel.getEntities();
+    String currentEntityName = null;
+    for (EntityType<?> entityTypeTemp : entityTypeSet) {
+      if (entityTypeTemp.getJavaType().getName().endsWith("." + entityName)) {
+        currentEntityName = entityTypeTemp.getName();
+        try {
+          jpaEntity = entityTypeTemp.getJavaType().newInstance();
+          break;
+        } catch (InstantiationException e) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.GENERAL
+                  .addContent(e.getMessage()), e);
+        } catch (IllegalAccessException e) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.GENERAL
+                  .addContent(e.getMessage()), e);
+        }
+      }
+    }
+
+    ODataEntry entryValues = null;
+    try {
+      entryValues = parseEntry(entitySet, content, requestContentType, true);
+    } catch (ODataBadRequestException e1) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e1.getMessage()), e1);
+    }
+
+    Map<String, Object> propertyValueMap = entryValues.getProperties();
+    parse2JPAEntityValueMap(jpaEntity, entityType, propertyValueMap, currentEntityName);
+
+    Map<EdmNavigationProperty, EdmEntitySet> navPropEntitySetMap = null;
+    try {
+      navPropEntitySetMap = createInlinedEntities(jpaEntity, entitySet, entryValues, currentEntityName);
+    } catch (ODataException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+    List<T> objectList = new ArrayList<T>();
+    objectList.add((T) jpaEntity);
+    objectList.add((T) navPropEntitySetMap);
+    return objectList;
+  }
+
+  @SuppressWarnings("unchecked")
+  public final Object parse2JPAEntityValueMap(
+      final Object jpaEntity, final EdmStructuralType edmEntityType, final Map<String, Object> propertyValueMap, final String entityName)
+      throws ODataJPARuntimeException {
+
+    if (jpaEntity == null || edmEntityType == null || propertyValueMap == null || propertyValueMap.size() == 0) {
+      return null;
+    }
+
+    String jpaEntityAccessKey = jpaEntity.getClass().getName();
+
+    if (!jpaEntityAccessMap.containsKey(jpaEntityAccessKey)) {
+      jpaEntityAccessMap.put(jpaEntityAccessKey,
+          getSetters(jpaEntity, edmEntityType, true));
+    }
+
+    HashMap<String, Method> setters = jpaEntityAccessMap
+        .get(jpaEntityAccessKey);
+    HashMap<String, String> embeddableKeys = jpaEmbeddableKeyMap
+        .get(jpaEntityAccessKey);
+    String propertyName = null;
+    try {
+      for (String key : setters.keySet()) {
+
+        EdmProperty property = (EdmProperty) edmEntityType
+            .getProperty(key);
+        if (property.getMapping() != null && property.getMapping().getInternalName() != null) {
+          propertyName = property.getMapping().getInternalName();
+        } else {
+          propertyName = property.getName();
+        }
+        Method method = setters.get(key);
+        Object propertyValue = propertyValueMap.get(key);
+        if (propertyValue == null) {
+          continue;
+        }
+        if (propertyValue instanceof java.util.GregorianCalendar) {
+          propertyValue = ((java.util.GregorianCalendar) propertyValue).getTime();
+        }
+
+        if (method != null) {
+          if (property.getType().getKind().equals(EdmTypeKind.COMPLEX)) {
+            Object complexObject = jpaComplexObjectMap.get(propertyName);
+            parse2JPAEntityValueMap(complexObject, ((EdmComplexType) property.getType()),
+                (Map<String, Object>) propertyValue, propertyName);
+            setters.get(key).invoke(jpaEntity, complexObject);
+          } else {
+            setters.get(key).invoke(jpaEntity, propertyValue);
+          }
+        }
+      }
+
+      if (embeddableKeys != null) {
+        Object embeddableKeyObj = null;
+        Method method = null;
+        for (String embeddableKey : embeddableKeys.keySet()) {
+          String name = embeddableKeys.get(embeddableKey);
+          String[] nameParts = name.split("\\.");//$NON-NLS-1$
+          Object propertyValue = jpaEntity;
+          Class<?> propertyClass = null;
+
+          try {
+            for (EntityType<?> entity : metamodel.getEntities())
+            {
+              if (entity.getName().equals(entityName))
+              {
+                Attribute<?, ?> attribute = entity.getAttribute(nameParts[0].substring(3, 4).toLowerCase() + nameParts[0].substring(4));
+                propertyClass = attribute.getJavaType();
+                if (embeddableKeyObj == null) {
+                  try {
+                    embeddableKeyObj = propertyClass.newInstance();
+                  } catch (InstantiationException e) {
+                    throw ODataJPARuntimeException
+                        .throwException(ODataJPARuntimeException.GENERAL
+                            .addContent(e.getMessage()), e);
+                  }
+                }
+                break;
+              }
+            }
+
+            method = propertyValue.getClass().getMethod(
+                nameParts[0], propertyClass);
+            populateEmbeddableKey(embeddableKeyObj, embeddableKey, nameParts[1], propertyValueMap);
+          } catch (NoSuchMethodException e) {
+            throw ODataJPARuntimeException
+                .throwException(ODataJPARuntimeException.GENERAL
+                    .addContent(e.getMessage()), e);
+          }
+        }
+        propertyName = "Embeddable Key";//$NON-NLS-1$
+        method.invoke(jpaEntity, embeddableKeyObj);
+      }
+    } catch (SecurityException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalAccessException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.ERROR_JPQL_PARAM_VALUE
+              .addContent(propertyName), e);
+    } catch (InvocationTargetException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+    return jpaEntity;
+  }
+
+  private void populateEmbeddableKey(final Object embeddableKeyObject, final String key, final String setterName, final Map<String, Object> propertyValueMap) throws ODataJPARuntimeException {
+    Class<?> propertyClass = jpaEmbeddableKeyObjectMap.get(key);
+    Method method = null;
+    try {
+      method = embeddableKeyObject.getClass().getMethod(setterName, propertyClass);
+    } catch (NoSuchMethodException e1) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e1.getMessage()), e1);
+    } catch (SecurityException e1) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e1.getMessage()), e1);
+    }
+    try {
+      method.invoke(embeddableKeyObject, propertyValueMap.get(key));
+    } catch (IllegalAccessException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.ERROR_JPQL_KEY_VALUE
+              .addContent(key), e);
+    } catch (InvocationTargetException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+  }
+
+  private <T> Map<EdmNavigationProperty, EdmEntitySet> createInlinedEntities(final T jpaEntity, final EdmEntitySet entitySet, final ODataEntry entryValues, final String jpaEntityName) throws ODataException {
+    if (jpaEntity == null) {
+      return null;
+    }
+    Map<String, Object> relatedPropertyValueMap = new HashMap<String, Object>();
+    Map<String, Class<?>> relatedClassMap = new HashMap<String, Class<?>>();
+    Map<EdmNavigationProperty, EdmEntitySet> navPropEntitySetMap = new HashMap<EdmNavigationProperty, EdmEntitySet>();
+    final EdmEntityType entityType = entitySet.getEntityType();
+    for (final String navigationPropertyName : entityType.getNavigationPropertyNames()) {
+      final EdmNavigationProperty navigationProperty = (EdmNavigationProperty) entityType.getProperty(navigationPropertyName);
+      List<ODataEntry> relatedValueList = null;
+      if (entryValues.getProperties().get(navigationPropertyName) != null) {
+        relatedValueList = ((ODataFeed) entryValues.getProperties().get(navigationPropertyName)).getEntries();
+      }
+      List<Object> relatedDataList = null;
+      if (relatedValueList != null) {
+        relatedDataList = new ArrayList<Object>();
+        final EdmEntitySet relatedEntitySet = entitySet.getRelatedEntitySet(navigationProperty);
+
+        for (final ODataEntry relatedValues : relatedValueList) {
+
+          String entityName = null;
+          EdmEntityType relatedEntityType = relatedEntitySet.getEntityType();
+          try {
+            if (relatedEntityType.getMapping() != null && relatedEntityType.getMapping().getInternalName() != null)
+            {
+              entityName = relatedEntityType.getMapping().getInternalName();
+            } else {
+              entityName = relatedEntityType.getName();
+            }
+          } catch (EdmException e1) {
+            throw ODataJPARuntimeException
+                .throwException(ODataJPARuntimeException.GENERAL
+                    .addContent(e1.getMessage()), e1);
+          }
+
+          Object relatedData = null;
+          Set<EntityType<?>> entityTypeSet = metamodel.getEntities();
+          String currentEntityName = null;
+          for (EntityType<?> entityTypeTemp : entityTypeSet) {
+            if (entityTypeTemp.getJavaType().getName().endsWith("." + entityName)) {
+              currentEntityName = entityTypeTemp.getName();
+              try {
+                relatedClassMap.put(navigationProperty.getMapping().getInternalName(), entityTypeTemp.getJavaType());
+                relatedData = entityTypeTemp.getJavaType().newInstance();
+                break;
+              } catch (InstantiationException e) {
+                throw ODataJPARuntimeException
+                    .throwException(ODataJPARuntimeException.GENERAL
+                        .addContent(e.getMessage()), e);
+              } catch (IllegalAccessException e) {
+                throw ODataJPARuntimeException
+                    .throwException(ODataJPARuntimeException.GENERAL
+                        .addContent(e.getMessage()), e);
+              }
+            }
+          }
+          if (relatedValues != null && relatedEntitySet != null) {
+            relatedDataList.add(relatedData);
+            if (navPropEntitySetMap.get(navigationProperty) == null) {
+              navPropEntitySetMap.put(navigationProperty, relatedEntitySet);
+            }
+            parse2JPAEntityValueMap(relatedData, relatedEntitySet.getEntityType(), relatedValues.getProperties(), currentEntityName);
+          } else {
+            continue;
+          }
+          createInlinedEntities(relatedData, relatedEntitySet, relatedValues, currentEntityName);
+        }
+      }
+      relatedPropertyValueMap.put(navigationProperty.getMapping().getInternalName(), relatedDataList);
+    }
+    setNavigationProperties(jpaEntity, entitySet, relatedPropertyValueMap, jpaEntityName, relatedClassMap);
+    return navPropEntitySetMap;
+  }
+
+  @SuppressWarnings("unchecked")
+  private void setNavigationProperties(
+      final Object jpaEntity, final EdmEntitySet entitySet, final Map<String, Object> propertyValueMap, final String entityName, final Map<String, Class<?>> relatedClassMap) throws ODataJPARuntimeException {
+    if (jpaEntity == null || entitySet == null || propertyValueMap == null || propertyValueMap.size() == 0) {
+      return;
+    }
+    List<HashMap<?, ?>> mapList = getSettersForNavigationProperties(jpaEntity, entitySet, relatedClassMap);
+    HashMap<String, Method> setters = (HashMap<String, Method>) mapList.get(0);
+    HashMap<String, EdmMultiplicity> multiplicityMap = (HashMap<String, EdmMultiplicity>) mapList.get(1);
+    for (String key : setters.keySet()) {
+      Method method = setters.get(key);
+      List<Object> propertyValue = (List<Object>) propertyValueMap.get(key);
+      if (propertyValue == null || propertyValue.size() == 0) {
+        continue;
+      }
+      try {
+        if (multiplicityMap.get(key) == EdmMultiplicity.MANY) {
+          method.invoke(jpaEntity, propertyValue);
+        } else {
+          method.invoke(jpaEntity, propertyValue.get(0));
+        }
+      } catch (IllegalAccessException e) {
+        throw ODataJPARuntimeException
+            .throwException(ODataJPARuntimeException.GENERAL
+                .addContent(e.getMessage()), e);
+      } catch (IllegalArgumentException e) {
+        throw ODataJPARuntimeException
+            .throwException(ODataJPARuntimeException.GENERAL
+                .addContent(e.getMessage()), e);
+      } catch (InvocationTargetException e) {
+        throw ODataJPARuntimeException
+            .throwException(ODataJPARuntimeException.GENERAL
+                .addContent(e.getMessage()), e);
+      }
+    }
+
+  }
+
+  private List<HashMap<?, ?>> getSettersForNavigationProperties(final Object jpaEntity, final EdmEntitySet edmEntitySet, final Map<String, Class<?>> relatedClassMap) throws ODataJPARuntimeException {
+    List<HashMap<?, ?>> mapList = new ArrayList<HashMap<?, ?>>();
+    HashMap<String, Method> setters = new HashMap<String, Method>();
+    HashMap<String, EdmMultiplicity> multiplicityMap = new HashMap<String, EdmMultiplicity>();
+    EdmEntityType edmEntityType = null;
+    try {
+      edmEntityType = edmEntitySet.getEntityType();
+    } catch (EdmException e2) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e2.getMessage()), e2);
+    }
+
+    try {
+      for (final String navigationPropertyName : edmEntityType.getNavigationPropertyNames()) {
+        final EdmNavigationProperty navigationProperty = (EdmNavigationProperty) edmEntityType.getProperty(navigationPropertyName);
+        String entityName = null;
+        try {
+          if (navigationProperty.getMapping() != null && navigationProperty.getMapping().getInternalName() != null)
+          {
+            entityName = navigationProperty.getMapping().getInternalName();
+          } else {
+            entityName = navigationProperty.getName();
+          }
+        } catch (EdmException e1) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.GENERAL
+                  .addContent(e1.getMessage()), e1);
+        }
+        String name = getSetterName(entityName);
+
+        Class<?> propertyClass = null;
+        if (navigationProperty.getMultiplicity() == EdmMultiplicity.MANY) {
+          propertyClass = List.class;
+          multiplicityMap.put(entityName, EdmMultiplicity.MANY);
+        } else {
+          propertyClass = relatedClassMap.get(entityName);
+          if (propertyClass == null) {
+            continue;
+          }
+          multiplicityMap.put(entityName, EdmMultiplicity.ONE);
+        }
+        try {
+          setters.put(
+              entityName,
+              jpaEntity.getClass().getDeclaredMethod(name, propertyClass));
+        } catch (NoSuchMethodException e) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.GENERAL
+                  .addContent(e.getMessage()), e);
+        } catch (SecurityException e) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.GENERAL
+                  .addContent(e.getMessage()), e);
+        }
+      }
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+    mapList.add(0, setters);
+    mapList.add(1, multiplicityMap);
+    return mapList;
+  }
+
+  private String getSetterName(final String navigationPropertyName)
+      throws ODataJPARuntimeException {
+    StringBuilder builder = new StringBuilder();
+    char c = Character.toUpperCase(navigationPropertyName.charAt(0));
+
+    builder.append("set").append(c).append(navigationPropertyName.substring(1)) //$NON-NLS-1$
+        .toString();
+    if (builder.length() > 0) {
+      return builder.toString();
+    } else {
+      return null;
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPALink.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPALink.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPALink.java
new file mode 100644
index 0000000..c1a3e8c
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPALink.java
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * 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.odata2.processor.core.jpa.cud;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.uri.UriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.processor.api.jpa.ODataJPAContext;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAProcessor;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.factory.ODataJPAFactory;
+import org.apache.olingo.odata2.processor.core.jpa.ODataEntityParser;
+import org.apache.olingo.odata2.processor.core.jpa.access.data.JPAEntityParser;
+
+public class JPALink {
+
+  private ODataJPAContext context;
+  private JPAProcessor jpaProcessor;
+  private ODataEntityParser parser;
+  private Object targetJPAEntity;
+  private Object sourceJPAEntity;
+
+  public JPALink(final ODataJPAContext context) {
+    this.context = context;
+    jpaProcessor = ODataJPAFactory.createFactory().getJPAAccessFactory()
+        .getJPAProcessor(this.context);
+    parser = new ODataEntityParser(this.context);
+  }
+
+  public void setSourceJPAEntity(final Object jpaEntity) {
+    sourceJPAEntity = jpaEntity;
+  }
+
+  public void create(final PostUriInfo uriInfo, final InputStream content, final String requestContentType, final String contentType)
+      throws ODataJPARuntimeException, ODataJPAModelException {
+
+    EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+    String targerEntitySetName;
+    EdmNavigationProperty navigationProperty = null;
+    try {
+      targerEntitySetName = targetEntitySet.getName();
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+
+    List<UriInfo> uriInfoList = new ArrayList<UriInfo>();
+
+    if (((UriInfo) uriInfo).isLinks()) {
+      UriInfo getUriInfo = parser.parseLink(targetEntitySet, content, requestContentType);
+      uriInfoList = new ArrayList<UriInfo>();
+      uriInfoList.add(getUriInfo);
+      navigationProperty = uriInfo.getNavigationSegments().get(0).getNavigationProperty();
+    }
+    else
+    {
+      uriInfoList = parser.parseLinks(targetEntitySet, content, contentType);
+    }
+
+    if (uriInfoList == null) {
+      return;
+    }
+    try {
+      for (UriInfo getUriInfo : uriInfoList) {
+
+        if (!getUriInfo.getTargetEntitySet().getName().equals(targerEntitySetName))
+        {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.RELATIONSHIP_INVALID, null);
+        }
+        if (!((UriInfo) uriInfo).isLinks()) {
+          navigationProperty = getUriInfo.getNavigationSegments().get(0).getNavigationProperty();
+        }
+
+        targetJPAEntity = jpaProcessor.process((GetEntityUriInfo) getUriInfo);
+        if (targetJPAEntity != null && ((UriInfo) uriInfo).isLinks()) {
+          getUriInfo = parser.parseLinkURI();
+          sourceJPAEntity = jpaProcessor.process((GetEntityUriInfo) getUriInfo);
+          if (sourceJPAEntity == null) {
+            throw ODataJPARuntimeException
+                .throwException(ODataJPARuntimeException.RESOURCE_X_NOT_FOUND.
+                    addContent(getUriInfo.getTargetEntitySet().getName()), null);
+          }
+        }
+
+        JPAEntityParser entityParser = JPAEntityParser.create();
+        Method setMethod = entityParser.getAccessModifier(sourceJPAEntity,
+            navigationProperty, JPAEntityParser.ACCESS_MODIFIER_SET);
+
+        Method getMethod = entityParser.getAccessModifier(sourceJPAEntity,
+            navigationProperty, JPAEntityParser.ACCESS_MODIFIER_GET);
+
+        if (getMethod.getReturnType().getTypeParameters() != null) {
+          @SuppressWarnings("unchecked")
+          List<Object> relatedEntities = (List<Object>) getMethod.invoke(sourceJPAEntity);
+          relatedEntities.add(targetJPAEntity);
+          setMethod.invoke(sourceJPAEntity, relatedEntities);
+        } else {
+          setMethod.invoke(sourceJPAEntity, targetJPAEntity);
+        }
+      }
+    } catch (IllegalAccessException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (InvocationTargetException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+  }
+
+  public void delete() {}
+
+  public void save() {
+    EntityManager em = context.getEntityManager();
+    EntityTransaction tx = em.getTransaction();
+
+    if (!tx.isActive()) {
+      em.getTransaction().begin();
+      em.persist(sourceJPAEntity);
+      em.getTransaction().commit();
+    }
+
+  }
+
+  public void update(final PutMergePatchUriInfo putUriInfo, final InputStream content,
+      final String requestContentType, final String contentType) throws ODataJPARuntimeException, ODataJPAModelException {
+    UriInfo uriInfo = (UriInfo) putUriInfo;
+
+    EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+    String targerEntitySetName;
+    EdmNavigationProperty navigationProperty = null;
+    try {
+      targerEntitySetName = targetEntitySet.getName();
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+
+    List<UriInfo> uriInfoList = new ArrayList<UriInfo>();
+
+    if (((UriInfo) uriInfo).isLinks()) {
+      UriInfo getUriInfo = parser.parseLink(targetEntitySet, content, requestContentType);
+      uriInfoList = new ArrayList<UriInfo>();
+      uriInfoList.add(getUriInfo);
+      navigationProperty = uriInfo.getNavigationSegments().get(0).getNavigationProperty();
+    }
+    else
+    {
+      uriInfoList = parser.parseLinks(targetEntitySet, content, contentType);
+    }
+
+    if (uriInfoList == null) {
+      return;
+    }
+    try {
+      for (UriInfo getUriInfo : uriInfoList) {
+
+        if (!getUriInfo.getTargetEntitySet().getName().equals(targerEntitySetName))
+        {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.RELATIONSHIP_INVALID, null);
+        }
+        if (!((UriInfo) uriInfo).isLinks()) {
+          navigationProperty = getUriInfo.getNavigationSegments().get(0).getNavigationProperty();
+        }
+
+        targetJPAEntity = jpaProcessor.process((GetEntityUriInfo) getUriInfo);
+        if (targetJPAEntity != null && ((UriInfo) uriInfo).isLinks()) {
+          getUriInfo = parser.parseLinkURI();
+          sourceJPAEntity = jpaProcessor.process((GetEntityUriInfo) getUriInfo);
+          if (sourceJPAEntity == null) {
+            throw ODataJPARuntimeException
+                .throwException(ODataJPARuntimeException.RESOURCE_X_NOT_FOUND.
+                    addContent(getUriInfo.getTargetEntitySet().getName()), null);
+          }
+        }
+
+        JPAEntityParser entityParser = JPAEntityParser.create();
+        Method setMethod = entityParser.getAccessModifier(sourceJPAEntity,
+            navigationProperty, JPAEntityParser.ACCESS_MODIFIER_SET);
+
+        Method getMethod = entityParser.getAccessModifier(sourceJPAEntity,
+            navigationProperty, JPAEntityParser.ACCESS_MODIFIER_GET);
+
+        if (getMethod.getReturnType().getTypeParameters() != null && getMethod.getReturnType().getTypeParameters().length != 0) {
+          @SuppressWarnings("unchecked")
+          List<Object> relatedEntities = (List<Object>) getMethod.invoke(sourceJPAEntity);
+          relatedEntities.add(targetJPAEntity);
+          setMethod.invoke(sourceJPAEntity, relatedEntities);
+        } else {
+          setMethod.invoke(sourceJPAEntity, targetJPAEntity);
+        }
+      }
+    } catch (IllegalAccessException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (InvocationTargetException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAUpdateRequest.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAUpdateRequest.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAUpdateRequest.java
new file mode 100644
index 0000000..b8ae487
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAUpdateRequest.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * 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.odata2.processor.core.jpa.cud;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+
+public class JPAUpdateRequest extends JPAWriteRequest {
+
+  public JPAUpdateRequest() {
+    super();
+  }
+
+  public void process(final Object jpaEntity, final PutMergePatchUriInfo putUriInfo, final InputStream content, final String requestContentType) throws ODataJPARuntimeException {
+
+    final EdmEntitySet entitySet = putUriInfo.getTargetEntitySet();
+    EdmEntityType entityType = null;
+    try {
+      entityType = entitySet.getEntityType();
+    } catch (EdmException e3) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e3.getMessage()), e3);
+    }
+
+    ODataEntry entryValues = null;
+    try {
+      entryValues = parseEntry(entitySet, content, requestContentType, false);
+    } catch (ODataBadRequestException e1) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e1.getMessage()), e1);
+    }
+    try {
+      Map<String, Object> propertValueMap = entryValues.getProperties();
+      parse2JPAEntityValueMap(jpaEntity, entityType, propertValueMap);
+    } catch (ODataJPARuntimeException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public final Object parse2JPAEntityValueMap(
+      final Object jpaEntity, final EdmStructuralType edmEntityType, final Map<String, Object> propertyValueMap)
+      throws ODataJPARuntimeException {
+
+    if (jpaEntity == null || edmEntityType == null || propertyValueMap == null) {
+      return null;
+    }
+
+    String jpaEntityAccessKey = jpaEntity.getClass().getName();
+
+    if (!jpaEntityAccessMap.containsKey(jpaEntityAccessKey)) {
+      jpaEntityAccessMap.put(jpaEntityAccessKey,
+          getSetters(jpaEntity, edmEntityType, false));
+    }
+
+    HashMap<String, Method> setters = jpaEntityAccessMap
+        .get(jpaEntityAccessKey);
+    List<EdmProperty> keyProperties = null;
+    if (edmEntityType instanceof EdmEntityType) {
+      try {
+        keyProperties = ((EdmEntityType) edmEntityType).getKeyProperties();
+      } catch (EdmException e) {
+        throw ODataJPARuntimeException
+            .throwException(ODataJPARuntimeException.GENERAL
+                .addContent(e.getMessage()), e);
+      }
+    }
+    boolean isKeyProperty = false;
+    String propertyName = null;
+    try {
+      for (String key : setters.keySet()) {
+        isKeyProperty = false;
+        if (keyProperties != null) {
+          for (EdmProperty keyProperty : keyProperties) {
+            if (keyProperty.getName().equalsIgnoreCase(key)) {
+              isKeyProperty = true;
+              break;
+            }
+          }
+          if (isKeyProperty) {
+            continue;
+          }
+        }
+        EdmProperty property = (EdmProperty) edmEntityType
+            .getProperty(key);
+        if (property.getMapping() != null && property.getMapping().getInternalName() != null) {
+          propertyName = property.getMapping().getInternalName();
+        } else {
+          propertyName = property.getName();
+        }
+        Method method = setters.get(key);
+        Object propertyValue = propertyValueMap.get(key);
+        if (propertyValue == null) {
+          continue;
+        }
+        if (propertyValue != null) {
+          if (propertyValue instanceof java.util.GregorianCalendar) {
+            propertyValue = ((java.util.GregorianCalendar) propertyValue).getTime();
+          }
+
+          if (method != null) {
+            if (property.getType().getKind().equals(EdmTypeKind.COMPLEX)) {
+              Object complexObject = jpaComplexObjectMap.get(propertyName);
+              parse2JPAEntityValueMap(complexObject, ((EdmComplexType) property.getType()),
+                  (Map<String, Object>) propertyValue);
+              setters.get(key).invoke(jpaEntity, complexObject);
+            } else {
+              setters.get(key).invoke(jpaEntity, propertyValue);
+            }
+          }
+        }
+
+      }
+    } catch (SecurityException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalAccessException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.ERROR_JPQL_PARAM_VALUE
+              .addContent(propertyName), e);
+    } catch (InvocationTargetException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+    return jpaEntity;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAWriteRequest.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAWriteRequest.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAWriteRequest.java
new file mode 100644
index 0000000..d8fd6d4
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAWriteRequest.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * 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.odata2.processor.core.jpa.cud;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.EdmTypeConvertor;
+import org.apache.olingo.odata2.processor.core.jpa.model.JPAEdmMappingImpl;
+
+public class JPAWriteRequest {
+  protected HashMap<String, HashMap<String, Method>> jpaEntityAccessMap = null;
+  protected HashMap<String, Object> jpaComplexObjectMap = null;
+  protected HashMap<String, HashMap<String, String>> jpaEmbeddableKeyMap = null;
+  protected HashMap<String, Class<?>> jpaEmbeddableKeyObjectMap = null;
+
+  public JPAWriteRequest() {
+    jpaEntityAccessMap = new HashMap<String, HashMap<String, Method>>();
+    jpaComplexObjectMap = new HashMap<String, Object>();
+  }
+
+  protected HashMap<String, Method> getSetters(final Object jpaEntity,
+      final EdmStructuralType structuralType, final boolean isCreate) throws ODataJPARuntimeException {
+
+    HashMap<String, Method> setters = new HashMap<String, Method>();
+    HashMap<String, String> embeddableKey = new HashMap<String, String>();
+    try {
+      for (String propertyName : structuralType.getPropertyNames()) {
+
+        EdmProperty property = (EdmProperty) structuralType
+            .getProperty(propertyName);
+        Class<?> propertyClass = null;
+        try {
+          if (property.getMapping() != null && ((JPAEdmMappingImpl) property.getMapping()).getJPAType() != null) {
+            propertyClass = ((JPAEdmMappingImpl) property.getMapping()).getJPAType();
+            if (property.getType().getKind().equals(EdmTypeKind.COMPLEX)) {
+              try {
+                if (((JPAEdmMappingImpl) property.getMapping()).getInternalName() != null) {
+                  jpaComplexObjectMap.put(((JPAEdmMappingImpl) property.getMapping()).getInternalName(), propertyClass.newInstance());
+                } else {
+                  jpaComplexObjectMap.put(propertyName, propertyClass.newInstance());
+                }
+              } catch (InstantiationException e) {
+                throw ODataJPARuntimeException
+                    .throwException(ODataJPARuntimeException.GENERAL
+                        .addContent(e.getMessage()), e);
+              } catch (IllegalAccessException e) {
+                throw ODataJPARuntimeException
+                    .throwException(ODataJPARuntimeException.GENERAL
+                        .addContent(e.getMessage()), e);
+              }
+            }
+          } else {
+            propertyClass = EdmTypeConvertor.convertToJavaType(property.getType());
+          }
+        } catch (ODataJPAModelException e) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.GENERAL
+                  .addContent(e.getMessage()), e);
+        }
+        String name = getSetterName(property);
+        String[] nameParts = name.split("\\.");
+        if (nameParts.length > 1) {
+          if (isCreate) {
+            jpaEmbeddableKeyObjectMap.put(propertyName, propertyClass);
+            embeddableKey.put(propertyName, name);
+          }
+        } else {
+          setters.put(
+              propertyName,
+              jpaEntity.getClass().getMethod(name, propertyClass));
+        }
+      }
+    } catch (NoSuchMethodException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (SecurityException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+
+    if (isCreate && !embeddableKey.isEmpty()) {
+      jpaEmbeddableKeyMap.put(jpaEntity.getClass().getName(),
+          embeddableKey);
+    }
+    return setters;
+  }
+
+  private String getSetterName(final EdmProperty property)
+      throws ODataJPARuntimeException {
+    EdmMapping mapping = null;
+    String name = null;
+    try {
+      mapping = property.getMapping();
+      if (mapping == null || mapping.getInternalName() == null) {
+        name = property.getName();
+      } else {
+        name = mapping.getInternalName();
+      }
+
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+
+    String[] nameParts = name.split("\\."); //$NON-NLS-1$
+    StringBuilder builder = new StringBuilder();
+
+    if (nameParts.length == 1) {
+      if (name != null) {
+        char c = Character.toUpperCase(name.charAt(0));
+
+        builder.append("set").append(c).append(name.substring(1)) //$NON-NLS-1$
+            .toString();
+      }
+    } else if (nameParts.length > 1) {
+
+      for (int i = 0; i < nameParts.length; i++) {
+        name = nameParts[i];
+        char c = Character.toUpperCase(name.charAt(0));
+        if (i == 0) {
+          builder.append("set").append(c).append(name.substring(1)); //$NON-NLS-1$
+        } else {
+          builder.append(".").append("set").append(c) //$NON-NLS-1$ //$NON-NLS-2$
+              .append(name.substring(1));
+        }
+      }
+    } else {
+      return null;
+    }
+
+    if (builder.length() > 0) {
+      return builder.toString();
+    } else {
+      return null;
+    }
+
+  }
+
+  protected ODataEntry parseEntry(final EdmEntitySet entitySet, final InputStream content, final String requestContentType, final boolean merge) throws ODataBadRequestException {
+    ODataEntry entryValues;
+    try {
+      EntityProviderReadProperties entityProviderProperties = EntityProviderReadProperties.init().mergeSemantic(merge).build();
+      entryValues = EntityProvider.readEntry(requestContentType, entitySet, content, entityProviderProperties);
+    } catch (EntityProviderException e) {
+      throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
+    }
+    return entryValues;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/edm/ODataJPAEdmProvider.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/edm/ODataJPAEdmProvider.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/edm/ODataJPAEdmProvider.java
new file mode 100644
index 0000000..edc3da9
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/edm/ODataJPAEdmProvider.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * 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.odata2.processor.core.jpa.edm;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
+import org.apache.olingo.odata2.api.edm.provider.Schema;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.processor.api.jpa.ODataJPAContext;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.factory.ODataJPAFactory;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmModelView;
+
+public class ODataJPAEdmProvider extends EdmProvider {
+
+  private ODataJPAContext oDataJPAContext;
+  private JPAEdmModelView jpaEdmModel;
+
+  private List<Schema> schemas;
+  private HashMap<String, EntityType> entityTypes;
+  private HashMap<String, EntityContainerInfo> entityContainerInfos;
+  private HashMap<String, ComplexType> complexTypes;
+  private HashMap<String, Association> associations;
+  private HashMap<String, FunctionImport> functionImports;
+
+  public ODataJPAEdmProvider() {
+    entityTypes = new HashMap<String, EntityType>();
+    entityContainerInfos = new HashMap<String, EntityContainerInfo>();
+    complexTypes = new HashMap<String, ComplexType>();
+    associations = new HashMap<String, Association>();
+    functionImports = new HashMap<String, FunctionImport>();
+  }
+
+  public ODataJPAEdmProvider(final ODataJPAContext oDataJPAContext) {
+    if (oDataJPAContext == null) {
+      throw new IllegalArgumentException(
+          ODataJPAException.ODATA_JPACTX_NULL);
+    }
+    entityTypes = new HashMap<String, EntityType>();
+    entityContainerInfos = new HashMap<String, EntityContainerInfo>();
+    complexTypes = new HashMap<String, ComplexType>();
+    associations = new HashMap<String, Association>();
+    functionImports = new HashMap<String, FunctionImport>();
+    jpaEdmModel = ODataJPAFactory.createFactory().getJPAAccessFactory()
+        .getJPAEdmModelView(oDataJPAContext);
+  }
+
+  public ODataJPAContext getODataJPAContext() {
+    return oDataJPAContext;
+  }
+
+  public void setODataJPAContext(final ODataJPAContext jpaContext) {
+    oDataJPAContext = jpaContext;
+  }
+
+  @Override
+  public EntityContainerInfo getEntityContainerInfo(final String name)
+      throws ODataException {
+
+    if (entityContainerInfos.containsKey(name)) {
+      return entityContainerInfos.get(name);
+    } else {
+
+      if (schemas == null) {
+        getSchemas();
+      }
+      List<EntityContainer> containerList = schemas.get(0).getEntityContainers();
+      if (containerList == null) return null;
+      for (EntityContainer container : containerList) {
+        if (name == null && container.isDefaultEntityContainer()) {
+          entityContainerInfos.put(name, container);
+          return container;
+        } else if (name != null && name.equals(container.getName())) {
+          return container;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public EntityType getEntityType(final FullQualifiedName edmFQName)
+      throws ODataException {
+
+    String strEdmFQName = edmFQName.toString();
+
+    if (edmFQName != null) {
+      if (entityTypes.containsKey(strEdmFQName)) {
+        return entityTypes.get(strEdmFQName);
+      } else if (schemas == null) {
+        getSchemas();
+      }
+
+      String entityTypeNamespace = edmFQName.getNamespace();
+      String entityTypeName = edmFQName.getName();
+
+      for (Schema schema : schemas) {
+        String schemaNamespace = schema.getNamespace();
+        if (schemaNamespace.equals(entityTypeNamespace)) {
+          if (schema.getEntityTypes() == null) return null;
+          for (EntityType et : schema.getEntityTypes()) {
+            if (et.getName().equals(entityTypeName)) {
+              entityTypes.put(strEdmFQName, et);
+              return et;
+            }
+          }
+        }
+      }
+    }
+
+    return null;
+  }
+
+  @Override
+  public ComplexType getComplexType(final FullQualifiedName edmFQName)
+      throws ODataException {
+
+    if (edmFQName != null) {
+      if (complexTypes.containsKey(edmFQName.toString())) {
+        return complexTypes.get(edmFQName.toString());
+      } else if (schemas == null) {
+        getSchemas();
+      }
+
+      for (Schema schema : schemas) {
+        if (schema.getNamespace().equals(edmFQName.getNamespace())) {
+          if (schema.getComplexTypes() == null) return null;
+          for (ComplexType ct : schema.getComplexTypes()) {
+            if (ct.getName().equals(edmFQName.getName())) {
+              complexTypes.put(edmFQName.toString(), ct);
+              return ct;
+            }
+          }
+        }
+      }
+    }
+
+    return null;
+  }
+
+  @Override
+  public Association getAssociation(final FullQualifiedName edmFQName)
+      throws ODataException {
+    if (edmFQName != null) {
+      if (associations.containsKey(edmFQName.toString())) {
+        return associations.get(edmFQName.toString());
+      } else if (schemas == null) {
+        getSchemas();
+      }
+
+      for (Schema schema : schemas) {
+        if (schema.getNamespace().equals(edmFQName.getNamespace())) {
+          if (schema.getAssociations() == null) return null;
+          for (Association association : schema.getAssociations()) {
+            if (association.getName().equals(
+                edmFQName.getName())) {
+              associations.put(edmFQName.toString(),
+                  association);
+              return association;
+            }
+          }
+        }
+      }
+
+    }
+    return null;
+  }
+
+  @Override
+  public EntitySet getEntitySet(final String entityContainer, final String name)
+      throws ODataException {
+
+    EntitySet returnedSet = null;
+    EntityContainer container = null;
+    if (!entityContainerInfos.containsKey(entityContainer)) {
+      container = (EntityContainer) getEntityContainerInfo(entityContainer);
+    } else {
+      container = (EntityContainer) entityContainerInfos
+          .get(entityContainer);
+    }
+
+    if (container != null && name != null) {
+      for (EntitySet es : container.getEntitySets()) {
+        if (name.equals(es.getName())) {
+          returnedSet = es;
+          break;
+        }
+      }
+    }
+
+    return returnedSet;
+  }
+
+  @Override
+  public AssociationSet getAssociationSet(final String entityContainer,
+      final FullQualifiedName association, final String sourceEntitySetName,
+      final String sourceEntitySetRole) throws ODataException {
+
+    EntityContainer container = null;
+    if (!entityContainerInfos.containsKey(entityContainer)) {
+      container = (EntityContainer) getEntityContainerInfo(entityContainer);
+    } else {
+      container = (EntityContainer) entityContainerInfos
+          .get(entityContainer);
+    }
+
+    if (container != null && association != null && container.getAssociationSets() != null) {
+      for (AssociationSet as : container.getAssociationSets()) {
+        if (association.equals(as.getAssociation())) {
+          AssociationSetEnd end = as.getEnd1();
+          if (sourceEntitySetName.equals(end.getEntitySet())
+              && sourceEntitySetRole.equals(end.getRole())) {
+            return as;
+          } else {
+            end = as.getEnd2();
+            if (sourceEntitySetName.equals(end.getEntitySet())
+                && sourceEntitySetRole.equals(end.getRole())) {
+              return as;
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public FunctionImport getFunctionImport(final String entityContainer, final String name)
+      throws ODataException {
+
+    if (functionImports.containsKey(name)) {
+      return functionImports.get(name);
+    }
+
+    EntityContainer container = null;
+    if (!entityContainerInfos.containsKey(entityContainer)) {
+      container = (EntityContainer) getEntityContainerInfo(entityContainer);
+    } else {
+      container = (EntityContainer) entityContainerInfos
+          .get(entityContainer);
+    }
+
+    if (container != null && name != null) {
+      if (container.getFunctionImports() == null) return null;
+      for (FunctionImport fi : container.getFunctionImports()) {
+        if (name.equals(fi.getName())) {
+          functionImports.put(name, fi);
+          return fi;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public List<Schema> getSchemas() throws ODataException {
+    if (schemas == null && jpaEdmModel != null) {
+      jpaEdmModel.getBuilder().build();
+      schemas = new ArrayList<Schema>();
+      schemas.add(jpaEdmModel.getEdmSchemaView().getEdmSchema());
+    }
+    if (jpaEdmModel == null) {
+
+      throw ODataJPAModelException.throwException(
+          ODataJPAModelException.BUILDER_NULL, null);
+    }
+
+    return schemas;
+
+  }
+
+}