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

[1/3] olingo-odata2 git commit: [OLINGO-515] - Support for Deep Insert in JSON format + Support for Linking entities in JSON format + Test Coverage Improvement + Enhancement to Reference Scenario

Repository: olingo-odata2
Updated Branches:
  refs/heads/master 5ea6d8c63 -> f8aa48392


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml b/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml
index 450c73b..0c8899c 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml
+++ b/odata2-jpa-processor/jpa-ref/src/main/resources/META-INF/persistence.xml
@@ -20,16 +20,15 @@
 		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Note</class>
 		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Store</class>
 		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Customer</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.CustomerBase</class>
 		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Category</class>
 		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Material</class>
-		<!-- <class>org.apache.olingo.odata2.jpa.processor.ref.model.AppointmentActivity</class>
-				<class>org.apache.olingo.odata2.jpa.processor.ref.model.Activity</class>
-		<class>org.apache.olingo.odata2.jpa.processor.ref.model.ActivityParty</class> -->
+		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Employee</class>
 		<class>org.apache.olingo.odata2.jpa.processor.ref.converter.BlobToByteConverter</class>
+		<class>org.apache.olingo.odata2.jpa.processor.ref.converter.ClobToStringConverter</class>
 		<properties>
 			<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
-			<property name="javax.persistence.jdbc.url"
-				value="jdbc:hsqldb:mem:org.apache.olingo.jpa.sample" />
+			<property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:apache.olingo.jpa.sample" />
 			<property name="javax.persistence.jdbc.user" value="sa" />
 			<property name="javax.persistence.jdbc.password" value="" />
 			<property name="eclipselink.target-database"

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-web/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/pom.xml b/odata2-jpa-processor/jpa-web/pom.xml
index 2854b0a..0e4cea0 100644
--- a/odata2-jpa-processor/jpa-web/pom.xml
+++ b/odata2-jpa-processor/jpa-web/pom.xml
@@ -66,6 +66,11 @@
 			<scope>provided</scope>
 		</dependency>
 		<dependency>
+			<groupId>org.eclipse.persistence</groupId>
+			<artifactId>javax.persistence</artifactId>
+			<version>${version.javax.persistence}</version>
+		</dependency>
+		<dependency>
 			<groupId>org.apache.cxf</groupId>
 			<artifactId>cxf-rt-frontend-jaxrs</artifactId>
 			<version>${cxf.version}</version>
@@ -109,7 +114,6 @@
 		<dependency>
 			<groupId>junit</groupId>
 			<artifactId>junit</artifactId>
-			<version>3.8.1</version>
 			<scope>test</scope>
 		</dependency>
 	</dependencies>

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
index 60679f8..256ffdd 100644
--- a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
+++ b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
@@ -47,7 +47,7 @@ public class JPAReferenceServiceFactory extends ODataJPAServiceFactory {
     oDataJPAContext
         .setJPAEdmExtension((JPAEdmExtension) new SalesOrderProcessingExtension());
     oDataJPAContext.setPageSize(PAGE_SIZE);
-    oDataJPAContext.setDefaultNaming(true);
+    oDataJPAContext.setDefaultNaming(false);
     setErrorLevel();
     setOnWriteJPAContent(onDBWriteContent);
 


[3/3] olingo-odata2 git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/olingo-odata2

Posted by ch...@apache.org.
Merge branch 'master' of
https://git-wip-us.apache.org/repos/asf/olingo-odata2

Conflicts:
	odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/JPAProcessorMockAbstract.java


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

Branch: refs/heads/master
Commit: f8aa483921ac562c44150b010a5b56574bed8ecb
Parents: 57ca646 5ea6d8c
Author: Chandan V A <ch...@sap.com>
Authored: Sun Feb 1 14:02:02 2015 +0530
Committer: Chandan V A <ch...@sap.com>
Committed: Sun Feb 1 14:02:02 2015 +0530

----------------------------------------------------------------------
 .../olingo/odata2/jpa/processor/core/mock/ODataContextMock.java  | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------



[2/3] olingo-odata2 git commit: [OLINGO-515] - Support for Deep Insert in JSON format + Support for Linking entities in JSON format + Test Coverage Improvement + Enhancement to Reference Scenario

Posted by ch...@apache.org.
[OLINGO-515] - Support for Deep Insert in JSON format + Support for
Linking entities in JSON format + Test Coverage Improvement +
Enhancement to Reference Scenario


Signed-off-by: Chandan V A <ch...@sap.com>

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

Branch: refs/heads/master
Commit: 57ca646d16fcd5bd81a3ada39997659836f86a50
Parents: 52a6342
Author: Chandan V A <ch...@sap.com>
Authored: Sun Feb 1 13:48:43 2015 +0530
Committer: Chandan V A <ch...@sap.com>
Committed: Sun Feb 1 13:58:47 2015 +0530

----------------------------------------------------------------------
 .../processor/core/access/data/JPAEntity.java   | 262 +++++++-------
 .../jpa/processor/core/access/data/JPALink.java | 160 +++++----
 .../core/access/model/JPAEdmNameBuilder.java    |   2 +-
 .../core/callback/JPATombstoneCallBack.java     |  12 +-
 .../processor/core/access/data/JPALinkTest.java | 344 +++++++++++++++++++
 .../core/access/model/JPATypeConvertorTest.java | 211 +++++++++++-
 .../core/callback/JPATombstoneCallBackTest.java |  42 +++
 .../core/mock/JPAProcessorMockAbstract.java     | 135 ++++++++
 .../jpa/processor/core/mock/PathInfoMock.java   |   4 +-
 .../processor/core/mock/data/EdmMockUtilV2.java |   8 +-
 .../jpa/processor/core/mock/data/Note.java      |  22 ++
 .../core/mock/data/SalesOrderHeader.java        |   9 +
 .../core/model/JPAEdmAssociationTest.java       |   6 +-
 .../src/test/resources/SalesOrderNotesLink.json |   1 +
 .../jpa-core/src/test/resources/metadata.xml    |  65 ++++
 odata2-jpa-processor/jpa-ref/pom.xml            |   2 +-
 .../ref/converter/ClobToStringConverter.java    |  69 ++++
 .../jpa/processor/ref/model/Category.java       |   2 +
 .../jpa/processor/ref/model/CategoryKey.java    |  78 +++++
 .../jpa/processor/ref/model/Customer.java       |  25 +-
 .../jpa/processor/ref/model/Material.java       |   2 +-
 .../odata2/jpa/processor/ref/model/Note.java    |   7 +-
 .../src/main/resources/META-INF/persistence.xml |   9 +-
 odata2-jpa-processor/jpa-web/pom.xml            |   6 +-
 .../ref/web/JPAReferenceServiceFactory.java     |   2 +-
 25 files changed, 1250 insertions(+), 235 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
index e0135b2..48ab4d9 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
@@ -61,7 +61,9 @@ public class JPAEntity {
   private JPAEntityParser jpaEntityParser = null;
   private ODataJPAContext oDataJPAContext;
   private OnJPAWriteContent onJPAWriteContent = null;
+  private List<String> relatedJPAEntityLink = new ArrayList<String>();
   public HashMap<String, List<Object>> relatedJPAEntityMap = null;
+  private EdmNavigationProperty viaNavigationProperty;
 
   public JPAEntity(final EdmEntityType oDataEntityType, final EdmEntitySet oDataEntitySet,
       final ODataJPAContext context) {
@@ -94,146 +96,59 @@ public class JPAEntity {
     return jpaEntity;
   }
 
-  @SuppressWarnings("unchecked")
-  private void write(final Map<String, Object> oDataEntryProperties,
-      final boolean isCreate)
-      throws ODataJPARuntimeException {
-    try {
-
-      EdmStructuralType structuralType = null;
-      final List<String> keyNames = oDataEntityType.getKeyPropertyNames();
-
-      if (isCreate) {
-        jpaEntity = instantiateJPAEntity();
-      } else if (jpaEntity == null) {
-        throw ODataJPARuntimeException
-            .throwException(ODataJPARuntimeException.RESOURCE_NOT_FOUND, null);
-      }
-
-      if (accessModifiersWrite == null) {
-        accessModifiersWrite =
-            jpaEntityParser.getAccessModifiers(jpaEntity, oDataEntityType, JPAEntityParser.ACCESS_MODIFIER_SET);
-      }
-
-      if (oDataEntityType == null || oDataEntryProperties == null) {
-        throw ODataJPARuntimeException
-            .throwException(ODataJPARuntimeException.GENERAL, null);
-      }
-
-      final HashMap<String, String> embeddableKeys =
-          jpaEntityParser.getJPAEmbeddableKeyMap(jpaEntity.getClass().getName());
-      Set<String> propertyNames = null;
-      if (embeddableKeys != null) {
-        setEmbeddableKeyProperty(embeddableKeys, oDataEntityType.getKeyProperties(), oDataEntryProperties,
-            jpaEntity);
-
-        propertyNames = new HashSet<String>();
-        propertyNames.addAll(oDataEntryProperties.keySet());
-        for (String key : embeddableKeys.keySet()) {
-          propertyNames.remove(key);
-        }
-      } else {
-        propertyNames = oDataEntryProperties.keySet();
-      }
-
-      for (String propertyName : propertyNames) {
-        EdmTyped edmTyped = (EdmTyped) oDataEntityType.getProperty(propertyName);
-
-        Method accessModifier = null;
-
-        switch (edmTyped.getType().getKind()) {
-        case SIMPLE:
-          if (isCreate == false) {
-            if (keyNames.contains(edmTyped.getName())) {
-              continue;
-            }
-          }
-          accessModifier = accessModifiersWrite.get(propertyName);
-          setProperty(accessModifier, jpaEntity, oDataEntryProperties.get(propertyName), (EdmSimpleType) edmTyped
-              .getType());
+  public void setViaNavigationProperty(EdmNavigationProperty viaNavigationProperty) {
+    this.viaNavigationProperty = viaNavigationProperty;
+  }
 
-          break;
-        case COMPLEX:
-          structuralType = (EdmStructuralType) edmTyped.getType();
-          accessModifier = accessModifiersWrite.get(propertyName);
-          setComplexProperty(accessModifier, jpaEntity,
-              structuralType,
-              (HashMap<String, Object>) oDataEntryProperties.get(propertyName));
-          break;
-        case NAVIGATION:
-        case ENTITY:
-          if (isCreate) {
-            structuralType = (EdmStructuralType) edmTyped.getType();
-            EdmNavigationProperty navProperty = (EdmNavigationProperty) edmTyped;
-            EdmEntitySet edmRelatedEntitySet = oDataEntitySet.getRelatedEntitySet(navProperty);
-            List<ODataEntry> relatedEntries = (List<ODataEntry>) oDataEntryProperties.get(propertyName);
-            if (relatedJPAEntityMap == null) {
-              relatedJPAEntityMap = new HashMap<String, List<Object>>();
-            }
-            List<Object> relatedJPAEntities = new ArrayList<Object>();
-            JPAEntity relatedEntity =
-                new JPAEntity((EdmEntityType) structuralType, edmRelatedEntitySet, oDataJPAContext);
-            for (ODataEntry oDataEntry : relatedEntries) {
-              relatedEntity.setParentJPAEntity(this);
-              relatedEntity.create(oDataEntry);
-              relatedJPAEntities.add(relatedEntity.getJPAEntity());
-            }
-            relatedJPAEntityMap.put(navProperty.getName(), relatedJPAEntities);
-          }
-        default:
-          continue;
-        }
-      }
-    } catch (Exception e) {
-      if (e instanceof ODataJPARuntimeException) {
-        throw (ODataJPARuntimeException) e;
-      }
-      throw ODataJPARuntimeException
-          .throwException(ODataJPARuntimeException.GENERAL
-              .addContent(e.getMessage()), e);
-    }
+  public EdmNavigationProperty getViaNavigationProperty() {
+    return viaNavigationProperty;
   }
 
   public void create(final ODataEntry oDataEntry) throws ODataJPARuntimeException {
+
     if (oDataEntry == null) {
       throw ODataJPARuntimeException
           .throwException(ODataJPARuntimeException.GENERAL, null);
     }
-    Map<String, Object> oDataEntryProperties = oDataEntry.getProperties();
-    if (oDataEntry.containsInlineEntry()) {
-      normalizeInlineEntries(oDataEntryProperties);
-    }
-    write(oDataEntryProperties, true);
-
-    EntryMetadata entryMetadata = oDataEntry.getMetadata();
-    List<String> leftNavPrpNames = new ArrayList<String>();
     try {
-      for (String navigationPropertyName : oDataEntityType.getNavigationPropertyNames()) {
-        List<String> links = entryMetadata.getAssociationUris(navigationPropertyName);
-        if (links.isEmpty()) {
-          continue;
-        } else {
+      EntryMetadata entryMetadata = oDataEntry.getMetadata();
+      Map<String, Object> oDataEntryProperties = oDataEntry.getProperties();
+      if (oDataEntry.containsInlineEntry()) {
+        normalizeInlineEntries(oDataEntryProperties);
+      }
+
+      if (oDataEntry.getProperties().size() > 0) {
+
+        write(oDataEntryProperties, true);
+
+        for (String navigationPropertyName : oDataEntityType.getNavigationPropertyNames()) {
           EdmNavigationProperty navProperty =
               (EdmNavigationProperty) oDataEntityType.getProperty(navigationPropertyName);
           if (relatedJPAEntityMap != null && relatedJPAEntityMap.containsKey(navigationPropertyName)) {
+            oDataEntry.getProperties().get(navigationPropertyName);
             JPALink.linkJPAEntities(relatedJPAEntityMap.get(navigationPropertyName), jpaEntity,
                 navProperty);
-          } else if (parentJPAEntity != null
-              &&
-              parentJPAEntity.getEdmEntitySet().getName().equals(
-                  oDataEntitySet.getRelatedEntitySet(navProperty).getName())) {
+            continue;
+          }
+          // The second condition is required to ensure that there is an explicit request to link
+          // two entities. Else the third condition will always be true for cases where two navigations
+          // point to same entity types.
+          if (parentJPAEntity != null
+              && navProperty.getRelationship().equals(getViaNavigationProperty().getRelationship())) {
             List<Object> targetJPAEntities = new ArrayList<Object>();
             targetJPAEntities.add(parentJPAEntity.getJPAEntity());
             JPALink.linkJPAEntities(targetJPAEntities, jpaEntity, navProperty);
-          } else {
-            leftNavPrpNames.add(navigationPropertyName);
+          } else if (!entryMetadata.getAssociationUris(navigationPropertyName).isEmpty()) {
+            if (!relatedJPAEntityLink.contains(navigationPropertyName)) {
+              relatedJPAEntityLink.add(navigationPropertyName);
+            }
           }
         }
       }
-      if (!leftNavPrpNames.isEmpty()) {
+      if (!relatedJPAEntityLink.isEmpty()) {
         JPALink link = new JPALink(oDataJPAContext);
         link.setSourceJPAEntity(jpaEntity);
-        link.create(oDataEntitySet, oDataEntry, leftNavPrpNames);
+        link.create(oDataEntitySet, oDataEntry, relatedJPAEntityLink);
       }
     } catch (EdmException e) {
       throw ODataJPARuntimeException
@@ -316,6 +231,7 @@ public class JPAEntity {
     }
   }
 
+  @SuppressWarnings({ "unchecked", "rawtypes" })
   protected void setProperty(final Method method, final Object entity, final Object entityPropertyValue,
       final EdmSimpleType type) throws
       IllegalAccessException, IllegalArgumentException, InvocationTargetException, ODataJPARuntimeException {
@@ -449,4 +365,114 @@ public class JPAEntity {
               .addContent(e.getMessage()), e);
     }
   }
+
+  @SuppressWarnings("unchecked")
+  private void write(final Map<String, Object> oDataEntryProperties,
+      final boolean isCreate)
+      throws ODataJPARuntimeException {
+    try {
+
+      EdmStructuralType structuralType = null;
+      final List<String> keyNames = oDataEntityType.getKeyPropertyNames();
+
+      if (isCreate) {
+        jpaEntity = instantiateJPAEntity();
+      } else if (jpaEntity == null) {
+        throw ODataJPARuntimeException
+            .throwException(ODataJPARuntimeException.RESOURCE_NOT_FOUND, null);
+      }
+
+      if (accessModifiersWrite == null) {
+        accessModifiersWrite =
+            jpaEntityParser.getAccessModifiers(jpaEntity, oDataEntityType, JPAEntityParser.ACCESS_MODIFIER_SET);
+      }
+
+      if (oDataEntityType == null || oDataEntryProperties == null) {
+        throw ODataJPARuntimeException
+            .throwException(ODataJPARuntimeException.GENERAL, null);
+      }
+
+      final HashMap<String, String> embeddableKeys =
+          jpaEntityParser.getJPAEmbeddableKeyMap(jpaEntity.getClass().getName());
+      Set<String> propertyNames = null;
+      if (embeddableKeys != null) {
+        setEmbeddableKeyProperty(embeddableKeys, oDataEntityType.getKeyProperties(), oDataEntryProperties,
+            jpaEntity);
+
+        propertyNames = new HashSet<String>();
+        propertyNames.addAll(oDataEntryProperties.keySet());
+        for (String key : embeddableKeys.keySet()) {
+          propertyNames.remove(key);
+        }
+      } else {
+        propertyNames = oDataEntryProperties.keySet();
+      }
+
+      for (String propertyName : propertyNames) {
+        EdmTyped edmTyped = (EdmTyped) oDataEntityType.getProperty(propertyName);
+
+        Method accessModifier = null;
+
+        switch (edmTyped.getType().getKind()) {
+        case SIMPLE:
+          if (isCreate == false) {
+            if (keyNames.contains(edmTyped.getName())) {
+              continue;
+            }
+          }
+          accessModifier = accessModifiersWrite.get(propertyName);
+          setProperty(accessModifier, jpaEntity, oDataEntryProperties.get(propertyName), (EdmSimpleType) edmTyped
+              .getType());
+
+          break;
+        case COMPLEX:
+          structuralType = (EdmStructuralType) edmTyped.getType();
+          accessModifier = accessModifiersWrite.get(propertyName);
+          setComplexProperty(accessModifier, jpaEntity,
+              structuralType,
+              (HashMap<String, Object>) oDataEntryProperties.get(propertyName));
+          break;
+        case NAVIGATION:
+        case ENTITY:
+          if (isCreate) {
+            structuralType = (EdmStructuralType) edmTyped.getType();
+            EdmNavigationProperty navProperty = (EdmNavigationProperty) edmTyped;
+            EdmEntitySet edmRelatedEntitySet = oDataEntitySet.getRelatedEntitySet(navProperty);
+            List<ODataEntry> relatedEntries = (List<ODataEntry>) oDataEntryProperties.get(propertyName);
+            if (relatedJPAEntityMap == null) {
+              relatedJPAEntityMap = new HashMap<String, List<Object>>();
+            }
+            List<Object> relatedJPAEntities = new ArrayList<Object>();
+            JPAEntity relatedEntity =
+                new JPAEntity((EdmEntityType) structuralType, edmRelatedEntitySet, oDataJPAContext);
+            for (ODataEntry oDataEntry : relatedEntries) {
+              relatedEntity.setParentJPAEntity(this);
+              relatedEntity.setViaNavigationProperty(navProperty);
+              relatedEntity.create(oDataEntry);
+              if (oDataEntry.getProperties().size() == 0) {
+                if (!oDataEntry.getMetadata().getUri().isEmpty()
+                    && !relatedJPAEntityLink.contains(navProperty.getName())) {
+                  relatedJPAEntityLink.add(navProperty.getName());
+                }
+              } else {
+                relatedJPAEntities.add(relatedEntity.getJPAEntity());
+              }
+            }
+            if (!relatedJPAEntities.isEmpty()) {
+              relatedJPAEntityMap.put(navProperty.getName(), relatedJPAEntities);
+            }
+          }
+        default:
+          continue;
+        }
+      }
+    } catch (Exception e) {
+      if (e instanceof ODataJPARuntimeException) {
+        throw (ODataJPARuntimeException) e;
+      }
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALink.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALink.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALink.java
index 72dbc15..64bf56c 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALink.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALink.java
@@ -147,33 +147,6 @@ public class JPALink {
     }
   }
 
-  private void delinkJPAEntities(final Object jpaEntity,
-      final List<Object> relatedJPAEntities,
-      final EdmNavigationProperty targetNavigationProperty)
-      throws ODataJPARuntimeException {
-
-    try {
-      JPAEntityParser entityParser = new JPAEntityParser();
-      Method setMethod = entityParser.getAccessModifier(jpaEntity.getClass(),
-          targetNavigationProperty, JPAEntityParser.ACCESS_MODIFIER_SET);
-
-      Method getMethod = entityParser.getAccessModifier(jpaEntity.getClass(),
-          targetNavigationProperty, JPAEntityParser.ACCESS_MODIFIER_GET);
-
-      if (getMethod.getReturnType().getTypeParameters() != null
-          && getMethod.getReturnType().getTypeParameters().length != 0) {
-        setMethod.invoke(jpaEntity, relatedJPAEntities);
-      } else {
-        setMethod.invoke(jpaEntity, (Object) null);
-      }
-    } catch (IllegalAccessException e) {
-      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    } catch (InvocationTargetException e) {
-      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    }
-
-  }
-
   public void save() {
     EntityManager em = context.getEntityManager();
     EntityTransaction tx = em.getTransaction();
@@ -197,10 +170,15 @@ public class JPALink {
       throws ODataJPARuntimeException,
       ODataJPAModelException {
 
+    List<Object> targetJPAEntities = new ArrayList<Object>();
     try {
       for (String navPropertyName : navigationPropertyNames) {
         List<String> links = oDataEntry.getMetadata().getAssociationUris(navPropertyName);
+        if (links == null || links.isEmpty() == true) {
+          links = extractLinkURI(oDataEntry, navPropertyName);
+        }
         if (links != null && links.isEmpty() == false) {
+
           EdmNavigationProperty navProperty = (EdmNavigationProperty) entitySet.getEntityType()
               .getProperty(
                   navPropertyName);
@@ -208,10 +186,14 @@ public class JPALink {
           for (String link : links) {
             UriInfo bindingUriInfo = parser.parseBindingLink(link, new HashMap<String, String>());
             targetJPAEntity = jpaProcessor.process((GetEntityUriInfo) bindingUriInfo);
-            List<Object> targetJPAEntities = new ArrayList<Object>();
-            targetJPAEntities.add(targetJPAEntity);
+            if (targetJPAEntity != null) {
+              targetJPAEntities.add(targetJPAEntity);
+            }
+          }
+          if (!targetJPAEntities.isEmpty()) {
             linkJPAEntities(targetJPAEntities, sourceJPAEntity, navProperty);
           }
+          targetJPAEntities.clear();
         }
       }
     } catch (EdmException e) {
@@ -220,30 +202,68 @@ public class JPALink {
 
   }
 
-  public void create(final PostUriInfo uriInfo) throws ODataJPARuntimeException,
-      ODataJPAModelException {
+  @SuppressWarnings("unchecked")
+  public static void linkJPAEntities(final Collection<Object> targetJPAEntities, final Object sourceJPAEntity,
+      final EdmNavigationProperty navigationProperty) throws ODataJPARuntimeException {
+    if (targetJPAEntities == null || sourceJPAEntity == null || navigationProperty == null) {
+      return;
+    }
     try {
-      int index = context.getODataContext().getPathInfo().getODataSegments().size() - 2;
-      UriInfo parsedUriInfo = parser.parseURISegment(index, index + 1);
-      Object targetJPAEntity = null;
-
-      if (parsedUriInfo != null) {
-        targetJPAEntity = jpaProcessor.process((GetEntityUriInfo) parsedUriInfo);
-        if (targetJPAEntity == null) {
-          throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.RESOURCE_X_NOT_FOUND
-              .addContent(parsedUriInfo.getTargetEntitySet().getName()), null);
+      JPAEntityParser entityParser = new JPAEntityParser();
+      Method setMethod = entityParser.getAccessModifier(sourceJPAEntity.getClass(),
+          navigationProperty, JPAEntityParser.ACCESS_MODIFIER_SET);
+      switch (navigationProperty.getMultiplicity()) {
+      case MANY:
+        Method getMethod = entityParser.getAccessModifier(sourceJPAEntity.getClass(),
+            navigationProperty, JPAEntityParser.ACCESS_MODIFIER_GET);
+        Collection<Object> relatedEntities = (Collection<Object>) getMethod.invoke(sourceJPAEntity);
+        if (relatedEntities == null) {
+          throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.ERROR_JPQL_CREATE_REQUEST, null);
         }
-        List<Object> targetJPAEntities = new ArrayList<Object>();
-        targetJPAEntities.add(sourceJPAEntity);
-        linkJPAEntities(targetJPAEntities, targetJPAEntity, uriInfo.getNavigationSegments().get(0)
-            .getNavigationProperty());
+        relatedEntities.addAll(targetJPAEntities);
+        setMethod.invoke(sourceJPAEntity, relatedEntities);
+        break;
+      case ONE:
+      case ZERO_TO_ONE:
+        setMethod.invoke(sourceJPAEntity, targetJPAEntities.iterator().next());
+        break;
       }
-
     } catch (EdmException e) {
-      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
-    } catch (ODataException e) {
-      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
+      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (IllegalAccessException e) {
+      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (InvocationTargetException e) {
+      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private List<String> extractLinkURI(ODataEntry oDataEntry, String navigationPropertyName) {
+
+    List<String> links = new ArrayList<String>();
+
+    String link = null;
+    Object object = oDataEntry.getProperties().get(navigationPropertyName);
+    if (object == null) {
+      return links;
+    }
+    if (object instanceof ODataEntry) {
+      link = ((ODataEntry) object).getMetadata().getUri();
+      if (!link.isEmpty()) {
+        links.add(link);
+      }
+    } else {
+      for (ODataEntry entry : (List<ODataEntry>) object) {
+        link = entry.getMetadata().getUri();
+        if (link != null && link.isEmpty() == false) {
+          links.add(link);
+        }
+      }
     }
+
+    return links;
   }
 
   private void modifyLink(final UriInfo uriInfo, final InputStream content, final String requestContentType,
@@ -292,40 +312,30 @@ public class JPALink {
     }
   }
 
-  @SuppressWarnings("unchecked")
-  public static void linkJPAEntities(final Collection<Object> targetJPAEntities, final Object sourceJPAEntity,
-      final EdmNavigationProperty navigationProperty) throws ODataJPARuntimeException {
-    if (targetJPAEntities == null || sourceJPAEntity == null || navigationProperty == null) {
-      return;
-    }
+  private void delinkJPAEntities(final Object jpaEntity,
+      final List<Object> relatedJPAEntities,
+      final EdmNavigationProperty targetNavigationProperty)
+      throws ODataJPARuntimeException {
+
     try {
       JPAEntityParser entityParser = new JPAEntityParser();
-      Method setMethod = entityParser.getAccessModifier(sourceJPAEntity.getClass(),
-          navigationProperty, JPAEntityParser.ACCESS_MODIFIER_SET);
-      switch (navigationProperty.getMultiplicity()) {
-      case MANY:
-        Method getMethod = entityParser.getAccessModifier(sourceJPAEntity.getClass(),
-            navigationProperty, JPAEntityParser.ACCESS_MODIFIER_GET);
-        Collection<Object> relatedEntities = (Collection<Object>) getMethod.invoke(sourceJPAEntity);
-        if(relatedEntities == null){
-          throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.ERROR_JPQL_CREATE_REQUEST, null);
-        }
-        relatedEntities.addAll(targetJPAEntities);
-        setMethod.invoke(sourceJPAEntity, relatedEntities);
-        break;
-      case ONE:
-      case ZERO_TO_ONE:
-        setMethod.invoke(sourceJPAEntity, targetJPAEntities.iterator().next());
-        break;
+      Method setMethod = entityParser.getAccessModifier(jpaEntity.getClass(),
+          targetNavigationProperty, JPAEntityParser.ACCESS_MODIFIER_SET);
+
+      Method getMethod = entityParser.getAccessModifier(jpaEntity.getClass(),
+          targetNavigationProperty, JPAEntityParser.ACCESS_MODIFIER_GET);
+
+      if (getMethod.getReturnType().getTypeParameters() != null
+          && getMethod.getReturnType().getTypeParameters().length != 0) {
+        setMethod.invoke(jpaEntity, relatedJPAEntities);
+      } else {
+        setMethod.invoke(jpaEntity, (Object) null);
       }
-    } catch (EdmException e) {
-      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
-    } catch (IllegalArgumentException e) {
-      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
     } catch (IllegalAccessException e) {
       throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
     } catch (InvocationTargetException e) {
       throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
     }
+
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java
index 352016e..72a4594 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java
@@ -410,7 +410,7 @@ public class JPAEdmNameBuilder {
       } else {
         associationName = end1Name + UNDERSCORE + end2Name;
       }
-      if (count > 1) {
+      if (count >= 1) {
         associationName = associationName + Integer.toString(count - 1);
       }
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java
index a462696..40b77d0 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBack.java
@@ -47,14 +47,20 @@ public class JPATombstoneCallBack implements TombstoneCallback {
 
   private String buildToken() {
     StringBuilder tokenBuilder = new StringBuilder();
-    tokenBuilder.append(baseUri);
+    if (baseUri != null) {
+      tokenBuilder.append(baseUri);
+    }
     try {
-      tokenBuilder.append(resultsView.getTargetEntitySet().getName());
+      if (resultsView != null) {
+        tokenBuilder.append(resultsView.getTargetEntitySet().getName());
+      }
     } catch (EdmException e) {
       // Nothing
     }
     tokenBuilder.append(DELTA_TOKEN_STRING);
-    tokenBuilder.append(deltaTokenValue);
+    if (deltaTokenValue != null) {
+      tokenBuilder.append(deltaTokenValue);
+    }
     return tokenBuilder.toString();
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java
index df614f5..27da81a 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPALinkTest.java
@@ -18,6 +18,350 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.jpa.processor.core.access.data;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.edm.Edm;
+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.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.Mapping;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.uri.KeyPredicate;
+import org.apache.olingo.odata2.api.uri.NavigationSegment;
+import org.apache.olingo.odata2.api.uri.PathSegment;
+import org.apache.olingo.odata2.api.uri.UriInfo;
+import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.core.edm.provider.EdmEntityTypeImplProv;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.mock.JPAProcessorMockAbstract;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataContextMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataJPAContextMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.PathInfoMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.PathSegmentMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.Note;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.SalesOrderHeader;
+import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
 public class JPALinkTest {
 
+  private static Edm edm;
+  private static SalesOrderHeader header;
+  private static Note note;
+  private static short testCase = 0;
+  private InputStream requestPayload = null;
+
+  @BeforeClass
+  public static void loadEdm() throws EntityProviderException {
+    edm = EntityProvider.readMetadata(JPALinkTest.class.getClassLoader().getResourceAsStream(
+        "metadata.xml"), false);
+  }
+
+  @Before
+  public void setUp() {
+    header = null;
+    note = null;
+    requestPayload = JPALinkTest.class.getClassLoader().getResourceAsStream(
+        "SalesOrderNotesLink.json");
+  }
+
+  @Test
+  public void testCreateLink() {
+    testCase = 0;
+    try {
+      ODataJPAContext context = mockODataJPAContext(false);
+      JPALink link = new JPALink(context);
+      Field processor = JPALink.class.
+          getDeclaredField("jpaProcessor");
+      processor.setAccessible(true);
+      processor.set(link, new JPAProcessorMock());
+      link.create(mockPostURIInfo(false), requestPayload, "application/json", "application/json");
+      assertEquals(2, header.getNotesDetails().size());
+
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (NoSuchFieldException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (IllegalArgumentException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (IllegalAccessException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testDeleteLink() {
+    testCase = 1;
+    try {
+      ODataJPAContext context = mockODataJPAContext(false);
+      JPALink link = new JPALink(context);
+      Field processor = JPALink.class.
+          getDeclaredField("jpaProcessor");
+      processor.setAccessible(true);
+      processor.set(link, new JPAProcessorMock());
+      link.delete(mockDeleteURIInfo(false));
+      assertNull(header.getNotesDetails());
+
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (NoSuchFieldException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (IllegalArgumentException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (IllegalAccessException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testDeleteLinkReverse() {
+    testCase = 1;
+    try {
+      ODataJPAContext context = mockODataJPAContext(true);
+      JPALink link = new JPALink(context);
+      Field processor = JPALink.class.
+          getDeclaredField("jpaProcessor");
+      processor.setAccessible(true);
+      processor.set(link, new JPAProcessorMock());
+      link.delete(mockDeleteURIInfo(true));
+      assertNull(note.getSalesOrderHeader());
+
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (NoSuchFieldException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (IllegalArgumentException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (IllegalAccessException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  private ODataJPAContext mockODataJPAContext(boolean isReverse) {
+
+    String path1 = null;
+    String path2 = null;
+    String path3 = null;
+
+    if (isReverse) {
+      path1 = "Notes('2')";
+      path2 = "$links";
+      path3 = "salesOrderHeader(1L)";
+    } else {
+      path1 = "SalesOrders(1L)";
+      path2 = "$links";
+      path3 = "NotesDetails('2')";
+    }
+
+    try {
+      List<PathSegment> pathSegments = new ArrayList<PathSegment>();
+
+      PathSegmentMock pathSegmentMock = new PathSegmentMock();
+      pathSegmentMock.setPath(path1);
+      pathSegments.add(pathSegmentMock);
+
+      pathSegmentMock = new PathSegmentMock();
+      pathSegmentMock.setPath(path2);
+      pathSegments.add(pathSegmentMock);
+
+      pathSegmentMock = new PathSegmentMock();
+      pathSegmentMock.setPath(path3);
+      pathSegments.add(pathSegmentMock);
+
+      PathInfoMock pathInfoMock = new PathInfoMock();
+
+      pathInfoMock.setServiceRootURI("http://localhost/so.svc");
+      pathInfoMock.setPathSegments(pathSegments);
+
+      ODataService service = EasyMock.createMock(ODataService.class);
+      EasyMock.expect(service.getEntityDataModel()).andReturn(edm).anyTimes();
+      EasyMock.replay(service);
+
+      ODataContextMock odataContextMock = new ODataContextMock();
+      odataContextMock.setPathInfo(pathInfoMock.mock());
+      odataContextMock.setODataService(service);
+      ODataJPAContext context = ODataJPAContextMock.mockODataJPAContext(odataContextMock.mock());
+
+      return context;
+    } catch (URISyntaxException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+    return null;
+  }
+
+  private List<NavigationSegment> mockNavigationSegments(boolean isReverse) throws EdmException, NoSuchFieldException,
+      SecurityException, IllegalArgumentException, IllegalAccessException {
+    Class<?> type = null;
+    String entityTypeName = null;
+    String keyLiteral = null;
+    EdmMultiplicity multiplicity = null;
+    String navPropertyName = null;
+    String toRole = null;
+    String associationName = null;
+
+    if (isReverse) {
+      type = SalesOrderHeader.class;
+      entityTypeName = "SalesOrder";
+      keyLiteral = "1";
+      multiplicity = EdmMultiplicity.ONE;
+      navPropertyName = "salesOrderHeader";
+      toRole = "SalesOrder";
+      associationName = "Note_SalesOrder";
+
+    } else {
+      type = List.class;
+      entityTypeName = "Note";
+      keyLiteral = "2";
+      multiplicity = EdmMultiplicity.MANY;
+      navPropertyName = "NotesDetails";
+      toRole = "Note";
+      associationName = "Note_SalesOrder";
+    }
+
+    JPAEdmMapping mapping = new JPAEdmMappingImpl();
+    mapping.setJPAType(type);
+
+    KeyPredicate keyPredicate = EasyMock.createMock(KeyPredicate.class);
+    EasyMock.expect(keyPredicate.getProperty()).andReturn(
+        edm.getEntityType("SalesOrderProcessing", entityTypeName).getKeyProperties().get(0)).anyTimes();
+    EasyMock.expect(keyPredicate.getLiteral()).andReturn(keyLiteral);
+    EasyMock.replay(keyPredicate);
+    List<KeyPredicate> keyPredicates = new ArrayList<KeyPredicate>();
+    keyPredicates.add(keyPredicate);
+
+    NavigationSegment navigationSegment = EasyMock.createMock(NavigationSegment.class);
+    EasyMock.expect(navigationSegment.getKeyPredicates()).andReturn(keyPredicates);
+
+    EdmNavigationProperty navProperty = EasyMock.createMock(EdmNavigationProperty.class);
+    EasyMock.expect(navProperty.getMapping()).andReturn((EdmMapping) mapping).anyTimes();
+    EasyMock.expect(navProperty.getMultiplicity()).andReturn(multiplicity).anyTimes();
+    EasyMock.expect(navProperty.getName()).andReturn(navPropertyName).anyTimes();
+    EasyMock.expect(navProperty.getToRole()).andReturn(toRole).anyTimes();
+    EasyMock.expect(navProperty.getRelationship()).andReturn(
+        edm.getAssociation("SalesOrderProcessing", associationName));
+    EasyMock.replay(navProperty);
+
+    EdmEntityType edmEntityType =
+        edm.getAssociation("SalesOrderProcessing", associationName).getEnd(toRole).getEntityType();
+    Field field = EdmEntityTypeImplProv.class.getDeclaredField("entityType");
+    field.setAccessible(true);
+
+    EntityType entityType = (EntityType) field.get(edmEntityType);
+    entityType.setMapping((Mapping) mapping);
+
+    EasyMock.expect(navigationSegment.getNavigationProperty()).andReturn(navProperty).anyTimes();
+    EasyMock.replay(navigationSegment);
+
+    List<NavigationSegment> navigationSegments = new ArrayList<NavigationSegment>();
+    navigationSegments.add(navigationSegment);
+
+    return navigationSegments;
+  }
+
+  private PostUriInfo mockPostURIInfo(boolean isReverse) throws ODataException, NoSuchMethodException,
+      SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
+
+    PostUriInfo uriInfo = EasyMock.createMock(UriInfo.class);
+    for (EdmEntitySet edmEntitySet : edm.getEntitySets()) {
+      if (edmEntitySet.getName().equals("Notes")) {
+        EasyMock.expect(uriInfo.getTargetEntitySet()).andReturn(edmEntitySet).anyTimes();
+        break;
+      }
+    }
+    EasyMock.expect(((UriInfo) uriInfo).isLinks()).andReturn(true);
+    EasyMock.expect(uriInfo.getNavigationSegments()).andReturn(mockNavigationSegments(isReverse)).anyTimes();
+    EasyMock.replay(uriInfo);
+
+    return uriInfo;
+  }
+
+  private DeleteUriInfo mockDeleteURIInfo(boolean isReverse) throws ODataException, NoSuchMethodException,
+      SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
+
+    DeleteUriInfo uriInfo = EasyMock.createMock(DeleteUriInfo.class);
+    EasyMock.expect(uriInfo.getNavigationSegments()).andReturn(mockNavigationSegments(isReverse)).anyTimes();
+    EasyMock.replay(uriInfo);
+
+    return uriInfo;
+  }
+
+  private static class JPAProcessorMock extends JPAProcessorMockAbstract {
+
+    @Override
+    public <T> Object process(GetEntityUriInfo uriParserResultView) throws ODataJPAModelException,
+        ODataJPARuntimeException {
+      try {
+
+        if (uriParserResultView.getTargetEntitySet().getName().equals("Notes")) {
+          assertEquals("id", uriParserResultView.getKeyPredicates().get(0).getProperty().getName());
+          header = new SalesOrderHeader();
+          note = new Note();
+          note.setSalesOrderHeader(header);
+          return note;
+        } else if (uriParserResultView.getTargetEntitySet().getName().equals("SalesOrders")) {
+          assertEquals("ID", uriParserResultView.getKeyPredicates().get(0).getProperty().getName());
+          header = new SalesOrderHeader();
+          Note note = new Note();
+          List<Note> notes = new ArrayList<Note>();
+          notes.add(note);
+          header.setNotesDetails(notes);
+          return header;
+        }
+
+      } catch (EdmException e) {
+        fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+      }
+      return null;
+
+    }
+
+    @Override
+    public List<Object> process(GetEntitySetUriInfo uriParserResultView) throws ODataJPAModelException,
+        ODataJPARuntimeException {
+
+      return null;
+
+    }
+
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertorTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertorTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertorTest.java
index 9325973..91639c4 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertorTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertorTest.java
@@ -19,19 +19,38 @@
 package org.apache.olingo.odata2.jpa.processor.core.access.model;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
 import java.math.BigDecimal;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.UUID;
 
+import javax.persistence.Lob;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
 import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
 import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
 import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.mock.model.JPAAttributeMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.model.JPAJavaMemberMock;
+import org.easymock.EasyMock;
 import org.junit.Test;
 
 public class JPATypeConvertorTest {
 
+  private static String testCase = "datetime";
+
   private EdmSimpleTypeKind edmSimpleKindTypeString;
+  private EdmSimpleTypeKind edmSimpleKindTypeCharacter;
   private EdmSimpleTypeKind edmSimpleKindTypeByteArr;
   private EdmSimpleTypeKind edmSimpleKindTypeLong;
   private EdmSimpleTypeKind edmSimpleKindTypeShort;
@@ -60,6 +79,7 @@ public class JPATypeConvertorTest {
     Boolean booleanObj = Boolean.TRUE;
     UUID uUID = new UUID(0, 0);
     SomeEnum someEnum = SomeEnum.TEST;
+    Character charObj = new Character('c');
 
     try {
       edmSimpleKindTypeString = JPATypeConvertor.convertToEdmSimpleType(str.getClass(), null);
@@ -73,10 +93,7 @@ public class JPATypeConvertorTest {
       edmSimpleKindTypeByte = JPATypeConvertor.convertToEdmSimpleType(byteObj.getClass(), null);
       edmSimpleKindTypeBoolean = JPATypeConvertor.convertToEdmSimpleType(booleanObj.getClass(), null);
       edmSimpleKindTypeStringFromEnum = JPATypeConvertor.convertToEdmSimpleType(someEnum.getClass(), null);
-      /*
-       * edmSimpleKindTypeDate = JPATypeConvertor
-       * .convertToEdmSimpleType(dateObj.getClass(),null);
-       */
+      edmSimpleKindTypeCharacter = JPATypeConvertor.convertToEdmSimpleType(charObj.getClass(), null);
       edmSimpleKindTypeUUID = JPATypeConvertor.convertToEdmSimpleType(uUID.getClass(), null);
     } catch (ODataJPAModelException e) {
       fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
@@ -92,9 +109,193 @@ public class JPATypeConvertorTest {
     assertEquals(EdmSimpleTypeKind.Decimal, edmSimpleKindTypeBigDecimal);
     assertEquals(EdmSimpleTypeKind.Byte, edmSimpleKindTypeByte);
     assertEquals(EdmSimpleTypeKind.Boolean, edmSimpleKindTypeBoolean);
-    // assertEquals(EdmSimpleTypeKind.DateTime, edmSimpleKindTypeDate);
+    assertEquals(EdmSimpleTypeKind.String, edmSimpleKindTypeCharacter);
     assertEquals(EdmSimpleTypeKind.Guid, edmSimpleKindTypeUUID);
     assertEquals(EdmSimpleTypeKind.String, edmSimpleKindTypeStringFromEnum);
   }
 
+  @Test
+  public void testConvertTypeCharacter() {
+    try {
+      assertEquals(EdmSimpleTypeKind.String, JPATypeConvertor.convertToEdmSimpleType(Character[].class, null));
+      assertEquals(EdmSimpleTypeKind.String, JPATypeConvertor.convertToEdmSimpleType(char[].class, null));
+      assertEquals(EdmSimpleTypeKind.String, JPATypeConvertor.convertToEdmSimpleType(char.class, null));
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testConvertTypeNumbers() {
+    try {
+      assertEquals(EdmSimpleTypeKind.Int64, JPATypeConvertor.convertToEdmSimpleType(long.class, null));
+      assertEquals(EdmSimpleTypeKind.Int16, JPATypeConvertor.convertToEdmSimpleType(short.class, null));
+      assertEquals(EdmSimpleTypeKind.Int32, JPATypeConvertor.convertToEdmSimpleType(int.class, null));
+      assertEquals(EdmSimpleTypeKind.Double, JPATypeConvertor.convertToEdmSimpleType(double.class, null));
+      assertEquals(EdmSimpleTypeKind.Single, JPATypeConvertor.convertToEdmSimpleType(float.class, null));
+      assertEquals(EdmSimpleTypeKind.Byte, JPATypeConvertor.convertToEdmSimpleType(byte.class, null));
+      assertEquals(EdmSimpleTypeKind.Boolean, JPATypeConvertor.convertToEdmSimpleType(boolean.class, null));
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testConvertTypeByteArray() {
+    try {
+      assertEquals(EdmSimpleTypeKind.Binary, JPATypeConvertor.convertToEdmSimpleType(Byte[].class, null));
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testConvertTypeBlob() {
+    testCase = "lob";
+    try {
+      assertEquals(EdmSimpleTypeKind.Binary, JPATypeConvertor.convertToEdmSimpleType(Blob.class,
+          new JPASimpleAttribute()));
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testConvertTypeClob() {
+    testCase = "lob";
+    try {
+      assertEquals(EdmSimpleTypeKind.String, JPATypeConvertor.convertToEdmSimpleType(Clob.class,
+          new JPASimpleAttribute()));
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testConvertTypeBLobNegative() {
+    try {
+      JPATypeConvertor.convertToEdmSimpleType(Blob.class, null);
+    } catch (ODataJPAModelException e) {
+      assertTrue(true);
+      return;
+    }
+    fail("ExceptionExpected");
+  }
+
+  @Test
+  public void testConvertTypeClobNegative() {
+    try {
+      JPATypeConvertor.convertToEdmSimpleType(Clob.class, null);
+    } catch (ODataJPAModelException e) {
+      assertTrue(true);
+      return;
+    }
+    fail("ExceptionExpected");
+  }
+
+  @Test
+  public void testConvertTypeCalendar() {
+    try {
+      assertEquals(EdmSimpleTypeKind.DateTime, JPATypeConvertor.convertToEdmSimpleType(Calendar.class, null));
+      assertEquals(EdmSimpleTypeKind.Time, JPATypeConvertor.convertToEdmSimpleType(Time.class, null));
+      assertEquals(EdmSimpleTypeKind.DateTime, JPATypeConvertor.convertToEdmSimpleType(Date.class, null));
+      assertEquals(EdmSimpleTypeKind.DateTime, JPATypeConvertor.convertToEdmSimpleType(Timestamp.class, null));
+      assertEquals(EdmSimpleTypeKind.DateTime, JPATypeConvertor.convertToEdmSimpleType(java.sql.Date.class, null));
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+      ;
+    }
+  }
+
+  @Test
+  public void testConvertTypeTemporal() {
+    testCase = "datetime";
+    try {
+      EdmSimpleTypeKind edmDateType = JPATypeConvertor.convertToEdmSimpleType(Calendar.class, new JPASimpleAttribute());
+      assertEquals(EdmSimpleTypeKind.DateTime, edmDateType);
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testConvertTypeTemporalTime() {
+    testCase = "time";
+    try {
+      EdmSimpleTypeKind edmTimeType = JPATypeConvertor.convertToEdmSimpleType(Calendar.class, new JPASimpleAttribute());
+      assertEquals(EdmSimpleTypeKind.Time, edmTimeType);
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testConvertTypeTemporalNull() {
+    testCase = "temporalnull";
+    try {
+      EdmSimpleTypeKind edmDateType = JPATypeConvertor.convertToEdmSimpleType(Calendar.class, new JPASimpleAttribute());
+      assertEquals(EdmSimpleTypeKind.DateTime, edmDateType);
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testConvertTypeTemporalNull2() {
+    testCase = "temporalnull2";
+    try {
+      EdmSimpleTypeKind edmDateType = JPATypeConvertor.convertToEdmSimpleType(Calendar.class, new JPASimpleAttribute());
+      assertEquals(EdmSimpleTypeKind.DateTime, edmDateType);
+    } catch (ODataJPAModelException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  private static class JPASimpleAttribute extends JPAAttributeMock<Object, String> {
+
+    @Override
+    public Member getJavaMember() {
+      if (testCase.equals("temporalNull2")) {
+        return null;
+      }
+      return new JPAJavaMember();
+    }
+  }
+
+  private static class JPAJavaMember extends JPAJavaMemberMock {
+
+    private Temporal temporal = null;
+    private Lob lob = null;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Annotation> T getAnnotation(final Class<T> annotationClass) {
+
+      if (testCase.equals("temporalnull")) {
+        return null;
+      }
+
+      if (annotationClass.equals(Temporal.class)) {
+        if (temporal == null) {
+          temporal = EasyMock.createMock(Temporal.class);
+          if (testCase.equals("datetime")) {
+            EasyMock.expect(temporal.value()).andReturn(TemporalType.TIMESTAMP).anyTimes();
+            EasyMock.replay(temporal);
+          } else if (testCase.equals("time")) {
+            EasyMock.expect(temporal.value()).andReturn(TemporalType.TIME).anyTimes();
+            EasyMock.replay(temporal);
+          }
+        }
+        return (T) temporal;
+      } else if (annotationClass.equals(Lob.class)) {
+        if (testCase.equals("lob")) {
+          lob = EasyMock.createMock(Lob.class);
+          EasyMock.replay(lob);
+        }
+        return (T) lob;
+      }
+      return null;
+
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBackTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBackTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBackTest.java
new file mode 100644
index 0000000..3f8ca92
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/callback/JPATombstoneCallBackTest.java
@@ -0,0 +1,42 @@
+package org.apache.olingo.odata2.jpa.processor.core.callback;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.ep.callback.TombstoneCallbackResult;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+public class JPATombstoneCallBackTest {
+
+  @Test
+  public void Test() {
+
+    EdmEntitySet edmEntitySet = EasyMock.createMock(EdmEntitySet.class);
+    try {
+      EasyMock.expect(edmEntitySet.getName()).andReturn("SalesOrder");
+      EasyMock.replay(edmEntitySet);
+    } catch (EdmException e) {
+      fail("Not Expected");
+    }
+    GetEntitySetUriInfo resultsView = EasyMock.createMock(GetEntitySetUriInfo.class);
+    EasyMock.expect(resultsView.getTargetEntitySet()).andReturn(edmEntitySet);
+    EasyMock.replay(resultsView);
+    JPATombstoneCallBack tombStoneCallBack = new JPATombstoneCallBack("/sample/", resultsView, "1");
+
+    TombstoneCallbackResult result = tombStoneCallBack.getTombstoneCallbackResult();
+    assertEquals("/sample/SalesOrder?!deltatoken=1", result.getDeltaLink());
+  }
+
+  @Test
+  public void TestNull() {
+
+    JPATombstoneCallBack tombStoneCallBack = new JPATombstoneCallBack(null, null, null);
+
+    TombstoneCallbackResult result = tombStoneCallBack.getTombstoneCallbackResult();
+    assertEquals("?!deltatoken=", result.getDeltaLink());
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/JPAProcessorMockAbstract.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/JPAProcessorMockAbstract.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/JPAProcessorMockAbstract.java
new file mode 100644
index 0000000..cee6069
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/JPAProcessorMockAbstract.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * 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.jpa.processor.core.mock;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityLinkUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.jpa.processor.api.access.JPAProcessor;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+
+public abstract class JPAProcessorMockAbstract implements JPAProcessor {
+
+  @Override
+  public <T> List<T> process(GetEntitySetUriInfo requestView) throws ODataJPAModelException, ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public <T> Object process(GetEntityUriInfo requestView) throws ODataJPAModelException, ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public long process(GetEntitySetCountUriInfo requestView) throws ODataJPAModelException, ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return 0;
+  }
+
+  @Override
+  public long process(GetEntityCountUriInfo resultsView) throws ODataJPAModelException, ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return 0;
+  }
+
+  @Override
+  public List<Object> process(GetFunctionImportUriInfo requestView) throws ODataJPAModelException,
+      ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Object process(GetEntityLinkUriInfo uriParserResultView) throws ODataJPAModelException,
+      ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public <T> List<T> process(GetEntitySetLinksUriInfo uriParserResultView) throws ODataJPAModelException,
+      ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Object process(PostUriInfo createView, InputStream content, String requestContentType)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Object process(PostUriInfo createView, Map<String, Object> content) throws ODataJPAModelException,
+      ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Object process(PutMergePatchUriInfo updateView, InputStream content, String requestContentType)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Object process(PutMergePatchUriInfo updateView, Map<String, Object> content) throws ODataJPAModelException,
+      ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public Object process(DeleteUriInfo deleteuriInfo, String contentType) throws ODataJPAModelException,
+      ODataJPARuntimeException {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public void process(PostUriInfo uriParserResultView, InputStream content, String requestContentType,
+      String contentType) throws ODataJPARuntimeException, ODataJPAModelException {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void process(PutMergePatchUriInfo uriParserResultView, InputStream content, String requestContentType,
+      String contentType) throws ODataJPARuntimeException, ODataJPAModelException {
+    // TODO Auto-generated method stub
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java
index b90b79c..0952ecf 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/PathInfoMock.java
@@ -41,8 +41,8 @@ public class PathInfoMock {
 
   public PathInfo mock() {
     PathInfo pathInfo = EasyMock.createMock(PathInfo.class);
-    EasyMock.expect(pathInfo.getODataSegments()).andReturn(pathSegments);
-    EasyMock.expect(pathInfo.getServiceRoot()).andReturn(uri);
+    EasyMock.expect(pathInfo.getODataSegments()).andReturn(pathSegments).anyTimes();
+    EasyMock.expect(pathInfo.getServiceRoot()).andReturn(uri).anyTimes();
 
     EasyMock.replay(pathInfo);
     return pathInfo;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java
index 23208ac..a5e32db 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtilV2.java
@@ -107,6 +107,7 @@ public class EdmMockUtilV2 {
           mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)).anyTimes();
       EasyMock.expect(entityType.getProperty(JPATypeMock.NAVIGATION_PROPERTY_X)).andReturn(
           mockEdmNavigationProperty(JPATypeMock.NAVIGATION_PROPERTY_X, EdmMultiplicity.ONE)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.NAVIGATION_PROPERTY_XS)).andReturn(null).anyTimes();
     } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
       EasyMock.expect(entityType.getProperty(JPARelatedTypeMock.PROPERTY_NAME_MLONG)).andReturn(
           mockEdmProperty(entityName, JPARelatedTypeMock.PROPERTY_NAME_MLONG)).anyTimes();
@@ -130,8 +131,11 @@ public class EdmMockUtilV2 {
 
   public static List<String> mockNavigationPropertyNames(final String entityName) {
     List<String> propertyNames = new ArrayList<String>();
-    propertyNames.add(JPATypeMock.NAVIGATION_PROPERTY_X);
-    propertyNames.add(JPATypeMock.NAVIGATION_PROPERTY_XS);
+    if (JPATypeMock.ENTITY_NAME.equals(entityName)) {
+
+      propertyNames.add(JPATypeMock.NAVIGATION_PROPERTY_X);
+      propertyNames.add(JPATypeMock.NAVIGATION_PROPERTY_XS);
+    }
     return propertyNames;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/Note.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/Note.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/Note.java
new file mode 100644
index 0000000..cedee66
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/Note.java
@@ -0,0 +1,22 @@
+package org.apache.olingo.odata2.jpa.processor.core.mock.data;
+
+public class Note {
+  private String id;
+  private SalesOrderHeader salesOrderHeader;
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public SalesOrderHeader getSalesOrderHeader() {
+    return salesOrderHeader;
+  }
+
+  public void setSalesOrderHeader(SalesOrderHeader salesOrderHeader) {
+    this.salesOrderHeader = salesOrderHeader;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/SalesOrderHeader.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/SalesOrderHeader.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/SalesOrderHeader.java
index 1236d96..195a9b3 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/SalesOrderHeader.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/SalesOrderHeader.java
@@ -35,6 +35,7 @@ public class SalesOrderHeader {
   }
 
   private List<SalesOrderLineItem> salesOrderLineItems = new ArrayList<SalesOrderLineItem>();
+  private List<Note> notes = new ArrayList<Note>();
 
   public String getDescription() {
     return description;
@@ -60,4 +61,12 @@ public class SalesOrderHeader {
     this.salesOrderLineItems = salesOrderLineItems;
   }
 
+  public List<Note> getNotesDetails() {
+    return notes;
+  }
+
+  public void setNotesDetails(List<Note> notes) {
+    this.notes = notes;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationTest.java
index eea4433..07d3208 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationTest.java
@@ -57,7 +57,7 @@ import org.junit.Test;
 public class JPAEdmAssociationTest extends JPAEdmTestModelView {
 
   private JPAEdmAssociation objAssociation = null;
-  private static String ASSOCIATION_NAME = "SalesOrderHeader_String";
+  private static String ASSOCIATION_NAME = "SalesOrderHeader_String0";
   private JPAEdmAssociationTest localView = null;
   private static final String PUNIT_NAME = "salesorderprocessing";
   private int variant;
@@ -347,7 +347,7 @@ public class JPAEdmAssociationTest extends JPAEdmTestModelView {
       Field field = objAssociation.getClass().getDeclaredField("associationEndMap");
       field.setAccessible(true);
       Map<String, JPAEdmAssociationEndView> associationEndMap = new HashMap<String, JPAEdmAssociationEndView>();
-      associationEndMap.put("SalesOrderHeader_String", objJPAEdmAssociationEnd);
+      associationEndMap.put("SalesOrderHeader_String0", objJPAEdmAssociationEnd);
       field.set(objAssociation, associationEndMap);
     } catch (ODataJPARuntimeException e) {
       fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
@@ -363,7 +363,7 @@ public class JPAEdmAssociationTest extends JPAEdmTestModelView {
       fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
     }
 
-    assertEquals("SalesOrderHeader_String", objAssociation.searchAssociation(objJPAEdmAssociationEnd).getName());
+    assertEquals("SalesOrderHeader_String0", objAssociation.searchAssociation(objJPAEdmAssociationEnd).getName());
 
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/resources/SalesOrderNotesLink.json
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/resources/SalesOrderNotesLink.json b/odata2-jpa-processor/jpa-core/src/test/resources/SalesOrderNotesLink.json
new file mode 100644
index 0000000..ad40515
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/test/resources/SalesOrderNotesLink.json
@@ -0,0 +1 @@
+{"uri":"Notes('1')"}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-core/src/test/resources/metadata.xml
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/resources/metadata.xml b/odata2-jpa-processor/jpa-core/src/test/resources/metadata.xml
new file mode 100644
index 0000000..1fd46a4
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/test/resources/metadata.xml
@@ -0,0 +1,65 @@
+<?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.
+-->
+<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
+	<edmx:DataServices m:DataServiceVersion="1.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
+		<Schema Namespace="SalesOrderProcessing" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
+			<EntityType Name="Note">
+				<Key>
+					<PropertyRef Name="id"/>
+				</Key>
+				<Property Name="id" Type="Edm.String" Nullable="false"/>
+				<Property Name="soId" Type="Edm.Int64" Nullable="true"/>
+				<Property Name="text" Type="Edm.String" Nullable="true" MaxLength="255"/>
+				<NavigationProperty Name="salesOrderHeader" Relationship="SalesOrderProcessing.Note_SalesOrder" FromRole="Note" ToRole="SalesOrder"/>
+			</EntityType>
+			<EntityType Name="SalesOrder">
+				<Key>
+					<PropertyRef Name="ID"/>
+				</Key>
+				<Property Name="ID" Type="Edm.Int64" Nullable="false"/>
+				<NavigationProperty Name="NotesDetails" Relationship="SalesOrderProcessing.Note_SalesOrder" FromRole="SalesOrder" ToRole="Note"/>
+			</EntityType>
+
+			<Association Name="Note_SalesOrder">
+				<End Type="SalesOrderProcessing.Note" Multiplicity="*" Role="Note"/>
+				<End Type="SalesOrderProcessing.SalesOrder" Multiplicity="1" Role="SalesOrder"/>
+				<ReferentialConstraint>
+					<Principal Role="SalesOrder">
+						<PropertyRef Name="ID"/>
+					</Principal>
+					<Dependent Role="Note">
+						<PropertyRef Name="soId"/>
+					</Dependent>
+				</ReferentialConstraint>
+			</Association>
+
+			<EntityContainer Name="SalesOrderProcessingContainer" m:IsDefaultEntityContainer="true">
+				<EntitySet Name="Notes" EntityType="SalesOrderProcessing.Note"/>
+				<EntitySet Name="SalesOrders" EntityType="SalesOrderProcessing.SalesOrder"/>
+
+				<AssociationSet Name="Note_SalesOrderSet" Association="SalesOrderProcessing.Note_SalesOrder">
+					<End EntitySet="Notes" Role="Note"/>
+					<End EntitySet="SalesOrders" Role="SalesOrder"/>
+				</AssociationSet>
+
+			</EntityContainer>
+		</Schema>
+	</edmx:DataServices>
+</edmx:Edmx>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-ref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/pom.xml b/odata2-jpa-processor/jpa-ref/pom.xml
index 478f1ea..9f2f706 100644
--- a/odata2-jpa-processor/jpa-ref/pom.xml
+++ b/odata2-jpa-processor/jpa-ref/pom.xml
@@ -75,7 +75,7 @@
 		<dependency>
 			<groupId>org.eclipse.persistence</groupId>
 			<artifactId>javax.persistence</artifactId>
-			<version>2.0.5</version>
+			<version>${version.javax.persistence}</version>
 		</dependency>
 		<dependency>
 			<groupId>org.hsqldb</groupId>

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/ClobToStringConverter.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/ClobToStringConverter.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/ClobToStringConverter.java
new file mode 100644
index 0000000..b9e73eb
--- /dev/null
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/ClobToStringConverter.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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.jpa.processor.ref.converter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+
+import org.hsqldb.jdbc.JDBCClob;
+
+@Converter(autoApply = true)
+public class ClobToStringConverter implements AttributeConverter<Clob, String> {
+
+  @Override
+  public String convertToDatabaseColumn(Clob clob) {
+
+    ByteArrayOutputStream os = new ByteArrayOutputStream();
+    try {
+      Reader reader = clob.getCharacterStream();
+
+      int byteRead = reader.read();
+      while (byteRead != -1) {
+        os.write(byteRead);
+        byteRead = reader.read();
+      }
+    } catch (IOException e) {
+      e.printStackTrace();
+    } catch (SQLException e) {
+      e.printStackTrace();
+    }
+    return os.toString();
+  }
+
+  @Override
+  public Clob convertToEntityAttribute(String string) {
+    if (string == null) {
+      return null;
+    }
+    Clob clob = null;
+    try {
+      clob = new JDBCClob(string);
+    } catch (SQLException e) {
+      e.printStackTrace();
+    }
+    return clob;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java
index d21e5bc..94315af 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Category.java
@@ -24,11 +24,13 @@ import java.util.List;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.IdClass;
 import javax.persistence.OneToMany;
 import javax.persistence.Table;
 
 @Entity
 @Table(name = "T_CATEGORY")
+@IdClass(value = CategoryKey.class)
 public class Category {
 
   @Id

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/CategoryKey.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/CategoryKey.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/CategoryKey.java
new file mode 100644
index 0000000..2e9a0fe
--- /dev/null
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/CategoryKey.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.jpa.processor.ref.model;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+public class CategoryKey implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  private char code[] = new char[2];
+  private long id;
+
+  public char[] getCode() {
+    return code;
+  }
+
+  public void setCode(char[] code) {
+    this.code = code;
+  }
+
+  public long getId() {
+    return id;
+  }
+
+  public void setId(long id) {
+    this.id = id;
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + Arrays.hashCode(code);
+    result = prime * result + (int) (id ^ (id >>> 32));
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    CategoryKey other = (CategoryKey) obj;
+    if (!Arrays.equals(code, other.code)) {
+      return false;
+    }
+    if (id != other.id) {
+      return false;
+    }
+
+    return true;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
index 3333b1f..bf5010b 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
@@ -19,16 +19,17 @@
 package org.apache.olingo.odata2.jpa.processor.ref.model;
 
 import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
 
+import javax.persistence.CascadeType;
 import javax.persistence.Column;
 import javax.persistence.Embedded;
 import javax.persistence.Entity;
 import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
-import javax.persistence.FetchType;
 import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
 import javax.persistence.Table;
 
 @Entity
@@ -52,21 +53,17 @@ public class Customer extends CustomerBase {
   @Column(name = "CREATED_AT")
   private Timestamp createdAt;
 
-  public Customer getInternal() {
-    return internal;
+  @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
+  private List<SalesOrderHeader> orders = new ArrayList<SalesOrderHeader>();
+
+  public List<SalesOrderHeader> getOrders() {
+    return orders;
   }
 
-  public void setInternal(Customer internal) {
-    this.internal = internal;
+  public void setOrders(List<SalesOrderHeader> orders) {
+    this.orders = orders;
   }
 
-//  @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
-//  private List<SalesOrderHeader> orders = new ArrayList<SalesOrderHeader>();
-  
-  @ManyToOne(fetch=FetchType.LAZY)
-  @JoinColumn(name="internal_id", referencedColumnName="ID")
-  private Customer internal;
-  
   public Long getId() {
     return id;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java
index f6e798c..5ec7647 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Material.java
@@ -60,7 +60,7 @@ public class Material {
 
   @Column(name = "MEASUREMENT_UNIT")
   private String measurementUnit;
-
+  
   @Lob
   @Column(name = "MIMAGE")
   @Convert(converter = org.apache.olingo.odata2.jpa.processor.ref.converter.BlobToByteConverter.class)

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/57ca646d/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java
index 434770e..85b2970 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Note.java
@@ -22,6 +22,7 @@ import java.sql.Clob;
 import java.util.Calendar;
 
 import javax.persistence.Column;
+import javax.persistence.Convert;
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.IdClass;
@@ -39,13 +40,12 @@ public class Note {
 
   public Note() {}
 
-  public Note(final Calendar creationTime, final Calendar creationDate, final String createdBy,
-      final Clob text) {
+  public Note(final Calendar creationTime, final Calendar creationDate, final String createdBy) {
     super();
     this.creationTime = creationTime;
     this.creationDate = creationDate;
     this.createdBy = createdBy;
-    this.text = text;
+
   }
 
   @Id
@@ -61,6 +61,7 @@ public class Note {
 
   @Column
   @Lob
+  @Convert(converter = org.apache.olingo.odata2.jpa.processor.ref.converter.ClobToStringConverter.class)
   private Clob text;
 
   @Column(name = "SO_ID")