olingo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chanda...@apache.org
Subject [2/2] git commit: [OLINGO-185] Handling java.sql.Blob and java.sql.Clob in JPA processor
Date Wed, 02 Apr 2014 11:51:14 GMT
[OLINGO-185] Handling java.sql.Blob and java.sql.Clob in JPA processor

New callback interface
org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent is
introduced. Implement this interface when Blob and Clob data types are
used as JPA entity property. OData JPA processor call backs the
implementation to fetch the JPA provider specific implementation of Blob
and Clob Objects.

The callback implementation needs to be registered via the method
setOnJPAWriteCallBack provided as part of ODataJPAServiceFactory class.



Signed-off-by: Chandan V A <chandan.v.a@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/ba0ff6be
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/ba0ff6be
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/ba0ff6be

Branch: refs/heads/master
Commit: ba0ff6beb9944f1a57115d5ed7367a3498f629fb
Parents: 1f37db3
Author: Chandan V A <chandan.v.a@sap.com>
Authored: Wed Apr 2 17:20:42 2014 +0530
Committer: Chandan V A <chandan.v.a@sap.com>
Committed: Wed Apr 2 17:20:42 2014 +0530

----------------------------------------------------------------------
 .../processor/api/ODataJPAServiceFactory.java   |  17 ++
 .../jpa/processor/api/OnJPAWriteContent.java    |  54 +++++
 .../api/exception/ODataJPARuntimeException.java |   5 +
 .../processor/core/access/data/JPAEntity.java   |  66 ++++--
 .../core/access/data/JPAEntityParser.java       | 105 +++++++++
 .../core/access/model/JPATypeConvertor.java     |  41 ++--
 .../main/resources/jpaprocessor_msg.properties  |   2 +
 .../JPAEntityParserTestForStaticMethods.java    |  79 +++++++
 .../core/access/data/JPAEntityTest.java         |  71 +++++-
 .../processor/core/mock/ODataContextMock.java   |  14 ++
 .../core/mock/ODataJPAContextMock.java          |   1 +
 .../core/mock/ODataJPAServiceFactoryMock.java   |  47 ++++
 .../core/mock/OnJPAWriteContentMock.java        |  58 +++++
 .../processor/core/mock/data/EdmMockUtilV2.java |  57 ++++-
 .../processor/core/mock/data/JPATypeMock.java   |  63 +++++
 .../core/mock/data/ODataEntryMockUtil.java      |  16 +-
 odata2-jpa-processor/jpa-ref/pom.xml            |  36 ++-
 .../ref/converter/BlobToByteConverter.java      |  64 +++++
 .../jpa/processor/ref/model/Material.java       |  21 ++
 .../odata2/jpa/processor/ref/model/Note.java    |  13 +-
 .../odata2/jpa/processor/ref/model/NoteKey.java |  65 +++++
 .../src/main/resources/META-INF/persistence.xml |   4 +
 odata2-jpa-processor/jpa-web/pom.xml            | 236 ++++++++++---------
 .../ref/extension/OnDBWriteContent.java         |  37 +++
 .../ref/web/JPAReferenceServiceFactory.java     |   4 +
 .../main/resources/SQL_Insert_Note.properties   |   2 +-
 26 files changed, 998 insertions(+), 180 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java
index 66d29f9..82aa68d 100644
--- a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java
+++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java
@@ -80,6 +80,7 @@ public abstract class ODataJPAServiceFactory extends ODataServiceFactory {
   private ODataJPAContext oDataJPAContext;
   private ODataContext oDataContext;
   private boolean setDetailErrors = false;
+  private OnJPAWriteContent onJPAWriteContent = null;
 
   /**
    * Creates an OData Service based on the values set in
@@ -176,6 +177,16 @@ public abstract class ODataJPAServiceFactory extends ODataServiceFactory {
     this.setDetailErrors = setDetailErrors;
   }
 
+  /**
+   * The methods sets the context with a callback implementation for JPA provider specific content.
+   * For details refer to {@link org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent}
+   * @param onJPAWriteContent is an instance of type
+   * {@link org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent}
+   */
+  protected void setOnWriteJPAContent(final OnJPAWriteContent onJPAWriteContent) {
+    this.onJPAWriteContent = onJPAWriteContent;
+  }
+
   @SuppressWarnings("unchecked")
   @Override
   public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
@@ -184,6 +195,12 @@ public abstract class ODataJPAServiceFactory extends ODataServiceFactory {
         return (T) new ODataJPAErrorCallback();
       }
     }
+
+    if (onJPAWriteContent != null) {
+      if (callbackInterface.isAssignableFrom(OnJPAWriteContent.class)) {
+        return (T) onJPAWriteContent;
+      }
+    }
     return null;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/OnJPAWriteContent.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/OnJPAWriteContent.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/OnJPAWriteContent.java
new file mode 100644
index 0000000..6be7492
--- /dev/null
+++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/OnJPAWriteContent.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.api;
+
+import java.sql.Blob;
+import java.sql.Clob;
+
+import org.apache.olingo.odata2.api.ODataCallback;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+
+/**
+ * <p> The interface is a call back interface that enables OData JPA Processor to get JPA provider specific
+ * implementation
+ * of <b>java.sql.Blob</b> and <b>java.sql.Clob</b> instances.</p>
+ * <p>
+ * Implement this interface if the JPA Model uses the data types java.sql.Blob and java.sql.Clob for its entity
+ * properties. </p>
+ * 
+ * 
+ */
+public interface OnJPAWriteContent extends ODataCallback {
+
+  /**
+   * Implement this method to instantiate JPA provider specific implementation of java.sql.Blob instance from an array
+   * of bytes.
+   * @param binaryData is an array of bytes
+   * @return an instance of type {@link java.sql.Blob}
+   */
+  public Blob getJPABlob(byte[] binaryData) throws ODataJPARuntimeException;
+
+  /**
+   * Implement this method to instantiate JPA provider specific implementation of java.sql.Clob instance from an array
+   * of characters.
+   * @param characterData is an array of characters
+   * @return an instance of type {@link java.sql.Clob}
+   */
+  public Clob getJPAClob(char[] characterData) throws ODataJPARuntimeException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java
index 46737bc..bac5ca3 100644
--- a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java
+++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java
@@ -66,6 +66,10 @@ public class ODataJPARuntimeException extends ODataJPAException {
       "RELATIONSHIP_INVALID");
   public static final MessageReference RESOURCE_X_NOT_FOUND = createMessageReference(ODataJPARuntimeException.class,
       "RESOURCE_X_NOT_FOUND");
+  public static final MessageReference ERROR_JPA_BLOB_NULL = createMessageReference(ODataJPARuntimeException.class,
+      "ERROR_JPA_BLOB_NULL");
+  public static final MessageReference ERROR_JPA_CLOB_NULL = createMessageReference(ODataJPARuntimeException.class,
+      "ERROR_JPA_CLOB_NULL");
 
   private ODataJPARuntimeException(final String localizedMessage, final Throwable e, final MessageReference msgRef) {
     super(localizedMessage, e, msgRef);
@@ -94,4 +98,5 @@ public class ODataJPARuntimeException extends ODataJPAException {
 
   private static final long serialVersionUID = -5230976355642443012L;
 
+
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/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 c7852d2..b263644 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
@@ -20,6 +20,9 @@ package org.apache.olingo.odata2.jpa.processor.core.access.data;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -32,6 +35,7 @@ import org.apache.olingo.odata2.api.edm.EdmEntityType;
 import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
 import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
 import org.apache.olingo.odata2.api.edm.EdmStructuralType;
 import org.apache.olingo.odata2.api.edm.EdmTypeKind;
 import org.apache.olingo.odata2.api.edm.EdmTyped;
@@ -39,6 +43,7 @@ import org.apache.olingo.odata2.api.ep.entry.EntryMetadata;
 import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
 import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent;
 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;
@@ -53,6 +58,7 @@ public class JPAEntity {
   private HashMap<String, Method> accessModifiersWrite = null;
   private JPAEntityParser jpaEntityParser = null;
   private ODataJPAContext oDataJPAContext;
+  private OnJPAWriteContent onJPAWriteContent = null;
   public HashMap<String, List<Object>> relatedJPAEntityMap = null;
 
   public JPAEntity(final EdmEntityType oDataEntityType, final EdmEntitySet oDataEntitySet,
@@ -67,6 +73,7 @@ public class JPAEntity {
       return;
     }
     jpaEntityParser = new JPAEntityParser();
+    onJPAWriteContent = oDataJPAContext.getODataContext().getServiceFactory().getCallback(OnJPAWriteContent.class);
   }
 
   public void setAccessModifersWrite(final HashMap<String, Method> accessModifiersWrite) {
@@ -140,7 +147,9 @@ public class JPAEntity {
             }
           }
           accessModifier = accessModifiersWrite.get(propertyName);
-          setProperty(accessModifier, jpaEntity, oDataEntryProperties.get(propertyName));
+          setProperty(accessModifier, jpaEntity, oDataEntryProperties.get(propertyName), (EdmSimpleType) edmTyped
+              .getType());
+
           break;
         case COMPLEX:
           structuralType = (EdmStructuralType) edmTyped.getType();
@@ -174,6 +183,9 @@ public class JPAEntity {
         }
       }
     } catch (Exception e) {
+      if (e instanceof ODataJPARuntimeException) {
+        throw (ODataJPARuntimeException) e;
+      }
       throw ODataJPARuntimeException
           .throwException(ODataJPARuntimeException.GENERAL
               .addContent(e.getMessage()), e);
@@ -279,7 +291,7 @@ public class JPAEntity {
   protected void setComplexProperty(Method accessModifier, final Object jpaEntity,
       final EdmStructuralType edmComplexType, final HashMap<String, Object> propertyValue)
       throws EdmException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
-      InstantiationException, ODataJPARuntimeException {
+      InstantiationException, ODataJPARuntimeException, NoSuchMethodException, SecurityException, SQLException {
 
     JPAEdmMapping mapping = (JPAEdmMapping) edmComplexType.getMapping();
     Object embeddableObject = mapping.getJPAType().newInstance();
@@ -296,27 +308,47 @@ public class JPAEntity {
         setComplexProperty(accessModifier, embeddableObject, structualType, (HashMap<String, Object>) propertyValue
             .get(edmPropertyName));
       } else {
-        setProperty(accessModifier, embeddableObject, propertyValue.get(edmPropertyName));
+        setProperty(accessModifier, embeddableObject, propertyValue.get(edmPropertyName), (EdmSimpleType) edmTyped
+            .getType());
       }
     }
   }
 
-  protected void setProperty(final Method method, final Object entity, final Object entityPropertyValue) throws
-      IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+  protected void setProperty(final Method method, final Object entity, final Object entityPropertyValue,
+      EdmSimpleType type) throws
+      IllegalAccessException, IllegalArgumentException, InvocationTargetException, ODataJPARuntimeException {
     if (entityPropertyValue != null) {
       Class<?> parameterType = method.getParameterTypes()[0];
-      if (parameterType.equals(char[].class)) {
-        char[] characters = ((String) entityPropertyValue).toCharArray();
-        method.invoke(entity, characters);
-      } else if (parameterType.equals(char.class)) {
-        char c = ((String) entityPropertyValue).charAt(0);
-        method.invoke(entity, c);
-      } else if (parameterType.equals(Character[].class)) {
-        Character[] characters = JPAEntityParser.toCharacterArray((String) entityPropertyValue);
-        method.invoke(entity, (Object) characters);
-      } else if (parameterType.equals(Character.class)) {
-        Character c = Character.valueOf(((String) entityPropertyValue).charAt(0));
-        method.invoke(entity, c);
+      if (type != null && type.getDefaultType().equals(String.class)) {
+        if (parameterType.equals(String.class)) {
+          method.invoke(entity, entityPropertyValue);
+        } else if (parameterType.equals(char[].class)) {
+          char[] characters = ((String) entityPropertyValue).toCharArray();
+          method.invoke(entity, characters);
+        } else if (parameterType.equals(char.class)) {
+          char c = ((String) entityPropertyValue).charAt(0);
+          method.invoke(entity, c);
+        } else if (parameterType.equals(Character[].class)) {
+          Character[] characters = JPAEntityParser.toCharacterArray((String) entityPropertyValue);
+          method.invoke(entity, (Object) characters);
+        } else if (parameterType.equals(Character.class)) {
+          Character c = Character.valueOf(((String) entityPropertyValue).charAt(0));
+          method.invoke(entity, c);
+        }
+      } else if (parameterType.equals(Blob.class)) {
+        if (onJPAWriteContent == null) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.ERROR_JPA_BLOB_NULL, null);
+        } else {
+          method.invoke(entity, onJPAWriteContent.getJPABlob((byte[]) entityPropertyValue));
+        }
+      } else if (parameterType.equals(Clob.class)) {
+        if (onJPAWriteContent == null) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.ERROR_JPA_CLOB_NULL, null);
+        } else {
+          method.invoke(entity, onJPAWriteContent.getJPAClob(((String) entityPropertyValue).toCharArray()));
+        }
       } else {
         method.invoke(entity, entityPropertyValue);
       }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParser.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParser.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParser.java
index 3930420..7fc9744 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParser.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParser.java
@@ -18,8 +18,16 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.jpa.processor.core.access.data;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringWriter;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -230,6 +238,10 @@ public final class JPAEntityParser {
         if (c != null) {
           propertyValue = toString(new Character[] { c });
         }
+      } else if (returnType.equals(Blob.class)) {
+        propertyValue = getBytes((Blob) method.invoke(entity));
+      } else if (returnType.equals(Clob.class)) {
+        propertyValue = getString((Clob) method.invoke(entity));
       } else {
         propertyValue = method.invoke(entity);
       }
@@ -246,6 +258,99 @@ public final class JPAEntityParser {
     return propertyValue;
   }
 
+  public static String getString(Clob clob) throws ODataJPARuntimeException {
+    try {
+      Reader stringReader = clob.getCharacterStream();
+      StringWriter buffer = null;
+      long clobSize = clob.length();
+      long remainingClobSize = clobSize;
+      int len = 0;
+      int off = 0;
+      boolean bufferNotEmpty = false;
+      if (clobSize > Integer.MAX_VALUE) {
+        buffer = new StringWriter(Integer.MAX_VALUE);
+        len = Integer.MAX_VALUE;
+        bufferNotEmpty = true;
+      } else {
+        buffer = new StringWriter((int) clobSize);
+        len = (int) clobSize;
+      }
+      stringReader = clob.getCharacterStream();
+      char c[] = new char[len];
+      while (remainingClobSize > len) {
+        stringReader.read(c, off, len);
+        buffer.write(c);
+        off = len + 1;
+        remainingClobSize = remainingClobSize - Integer.MAX_VALUE;
+        if (remainingClobSize > Integer.MAX_VALUE) {
+          len = Integer.MAX_VALUE;
+        } else {
+          len = (int) remainingClobSize;
+        }
+      }
+      if (remainingClobSize <= len) {
+        stringReader.read(c, off, len);
+      }
+      if (bufferNotEmpty) {
+        return buffer.toString();
+      } else {
+        return new String(c);
+      }
+
+    } catch (SQLException e) {
+      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (IOException e) {
+      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    }
+
+  }
+
+  public static byte[] getBytes(Blob blob) throws ODataJPARuntimeException {
+    try {
+      InputStream is = null;
+      ByteArrayOutputStream buffer = null;
+      long blobSize = blob.length();
+      long remainingBlobSize = blobSize;
+      int len = 0;
+      int off = 0;
+      boolean bufferNotEmpty = false;
+      if (blobSize > Integer.MAX_VALUE) { // Edge case when the Blob Size is more than 2GB
+        buffer = new ByteArrayOutputStream(Integer.MAX_VALUE);
+        len = Integer.MAX_VALUE;
+        bufferNotEmpty = true;
+      } else {
+        buffer = new ByteArrayOutputStream((int) blobSize);
+        len = (int) blobSize;
+      }
+
+      is = blob.getBinaryStream();
+      byte b[] = new byte[len];
+      while (remainingBlobSize > len) {
+        is.read(b, off, len);
+        buffer.write(b);
+        off = len + 1;
+        remainingBlobSize = remainingBlobSize - Integer.MAX_VALUE;
+        if (remainingBlobSize > Integer.MAX_VALUE) {
+          len = Integer.MAX_VALUE;
+        } else {
+          len = (int) remainingBlobSize;
+        }
+      }
+      if (remainingBlobSize <= len) {
+        is.read(b, off, len);
+      }
+      if (bufferNotEmpty) {
+        return buffer.toByteArray();
+      } else {
+        return b;
+      }
+    } catch (SQLException e) {
+      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (IOException e) {
+      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    }
+  }
+
   public Object getEmbeddablePropertyValue(final String methodName, final Object jpaEntity)
       throws ODataJPARuntimeException {
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertor.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertor.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertor.java
index e35e4cf..c5c2722 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertor.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPATypeConvertor.java
@@ -18,12 +18,15 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.jpa.processor.core.access.model;
 
-import java.lang.reflect.Field;
+import java.lang.reflect.AnnotatedElement;
 import java.math.BigDecimal;
+import java.sql.Blob;
+import java.sql.Clob;
 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 javax.persistence.metamodel.Attribute;
@@ -53,8 +56,6 @@ public class JPATypeConvertor {
    * @see EdmSimpleTypeKind
    */
 
-  private static final String OBJECT_TYPE = "java.lang.Object";
-
   public static EdmSimpleTypeKind
       convertToEdmSimpleType(final Class<?> jpaType, final Attribute<?, ?> currentAttribute)
           throws ODataJPAModelException {
@@ -78,14 +79,12 @@ public class JPATypeConvertor {
       return EdmSimpleTypeKind.Binary;
     } else if (jpaType.equals(Byte.class) || jpaType.equals(byte.class)) {
       return EdmSimpleTypeKind.Byte;
-    } else if (jpaType.equals(Byte[].class)) {
-      return EdmSimpleTypeKind.Binary;
     } else if (jpaType.equals(Boolean.class) || jpaType.equals(boolean.class)) {
       return EdmSimpleTypeKind.Boolean;
     } else if ((jpaType.equals(Date.class)) || (jpaType.equals(Calendar.class))) {
       try {
         if ((currentAttribute != null)
-            && (determineTemporalType(currentAttribute.getDeclaringType().getJavaType(), currentAttribute.getName())
+            && (determineTemporalType(currentAttribute)
               == TemporalType.TIME)) {
           return EdmSimpleTypeKind.Time;
         } else {
@@ -96,21 +95,33 @@ public class JPATypeConvertor {
       }
     } else if (jpaType.equals(UUID.class)) {
       return EdmSimpleTypeKind.Guid;
+    } else if (jpaType.equals(Byte[].class)) {
+      return EdmSimpleTypeKind.Binary;
+    } else if (jpaType.equals(Blob.class) && isBlob(currentAttribute)) {
+      return EdmSimpleTypeKind.Binary;
+    } else if (jpaType.equals(Clob.class) && isBlob(currentAttribute)) {
+      return EdmSimpleTypeKind.String;
     }
     throw ODataJPAModelException.throwException(ODataJPAModelException.TYPE_NOT_SUPPORTED
         .addContent(jpaType.toString()), null);
   }
 
-  private static TemporalType determineTemporalType(final Class<?> type, final String fieldName)
+  private static boolean isBlob(Attribute<?, ?> currentAttribute) {
+    if (currentAttribute != null) {
+      AnnotatedElement annotatedElement = (AnnotatedElement) currentAttribute.getJavaMember();
+      if (annotatedElement != null && annotatedElement.getAnnotation(Lob.class) != null) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private static TemporalType determineTemporalType(Attribute<?, ?> currentAttribute)
       throws ODataJPAModelException {
-    if (type != null && !type.getName().equals(OBJECT_TYPE)) {
-      try {
-        Field field = type.getField(fieldName);
-        return field.getAnnotation(Temporal.class).value();
-      } catch (NoSuchFieldException e) {
-        determineTemporalType(type.getSuperclass(), fieldName);
-      } catch (SecurityException e) {
-        throw ODataJPAModelException.throwException(ODataJPAModelException.GENERAL.addContent(e.getMessage()), e);
+    if (currentAttribute != null) {
+      AnnotatedElement annotatedElement = (AnnotatedElement) currentAttribute.getJavaMember();
+      if (annotatedElement != null && annotatedElement.getAnnotation(Temporal.class) != null) {
+        return annotatedElement.getAnnotation(Temporal.class).value();
       }
     }
     return null;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties b/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties
index db8d857..7788d49 100644
--- a/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties
+++ b/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties
@@ -55,6 +55,8 @@ org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.ER
 org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.ERROR_JPQL_INTEGRITY_CONSTRAINT="Integrity constraint violation"
 org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.RELATIONSHIP_INVALID="OData - JPA Runtime: Invalid link"
 org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.RESOURCE_X_NOT_FOUND="OData - JPA Runtime: Resource [%1$s] not found"
+org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.ERROR_JPA_BLOB_NULL="OData - JPA Runtime: Blob data type is null. Initialize Blob type by implementing callback interface org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent.
+org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.ERROR_JPA_CLOB_NULL="OData - JPA Runtime: Clob data type is null. Initialize Clob type by implementing callback interface org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent.
 
 #JPA Common Errors
 org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAException.ODATA_JPACTX_NULL="OData JPA: OData JPA Context cannot be null"

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserTestForStaticMethods.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserTestForStaticMethods.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserTestForStaticMethods.java
index 22bac6c..44f1f4b 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserTestForStaticMethods.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserTestForStaticMethods.java
@@ -23,7 +23,19 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.lang.reflect.Method;
+import java.net.URL;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+import javax.sql.rowset.serial.SerialException;
 
 import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
 import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
@@ -213,6 +225,73 @@ public class JPAEntityParserTestForStaticMethods {
     }
   }
 
+  @Test
+  public void testGetString() {
+    char[] expectedChar = new char[] { 'a', 'b', 'c' };
+    try {
+      Clob clob = new SerialClob(expectedChar);
+      String actualString = JPAEntityParser.getString(clob);
+
+      assertEquals(new String(expectedChar), actualString);
+
+    } catch (SerialException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SQLException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  @Test
+  public void testGetBytes() {
+    final String fileName = "SalesOrderProcessingMappingModels.xml";
+
+    try {
+      FileInputStream fis = getFileStream(fileName);
+
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      int content = fis.read();
+      while (content != -1) {
+        baos.write(content);
+        content = fis.read();
+      }
+      Blob blob = new SerialBlob(baos.toByteArray());
+      byte[] actualBytes = (byte[]) JPAEntityParser.getBytes(blob);
+      byte[] expectedBytes = baos.toByteArray();
+
+      assertEquals(expectedBytes.length, actualBytes.length);
+      int size = actualBytes.length;
+      int index = 0;
+      while (index < size) {
+        assertEquals(expectedBytes[index], actualBytes[index]);
+        index++;
+      }
+
+    } catch (FileNotFoundException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SerialException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SQLException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (IOException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+  private FileInputStream getFileStream(String name) throws SerialException, FileNotFoundException {
+    final String fileName = "SalesOrderProcessingMappingModels.xml";
+    FileInputStream fis;
+
+    URL fileURL = JPAEntityParserTestForStaticMethods.class.getClassLoader().getResource(fileName);
+    fis = new FileInputStream(fileURL.getPath());
+
+    return fis;
+
+  }
+
   public Character getCharacter() {
     return new Character('A');
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java
index 71e2204..3bfac96 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityTest.java
@@ -26,8 +26,12 @@ import static org.junit.Assert.fail;
 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.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
 import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
 import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+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.data.EdmMockUtilV2;
 import org.apache.olingo.odata2.jpa.processor.core.mock.data.JPATypeMock;
@@ -47,7 +51,7 @@ public class JPAEntityTest {
       EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, true);
       EdmEntityType edmEntityType = edmEntitySet.getEntityType();
 
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, null);
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
       jpaEntity.create(ODataEntryMockUtil.mockODataEntryWithComplexType(JPATypeMock.ENTITY_NAME));
     } catch (ODataJPARuntimeException e) {
       fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
@@ -55,6 +59,9 @@ public class JPAEntityTest {
     } catch (EdmException 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);
     }
     JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
     assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
@@ -76,7 +83,7 @@ public class JPAEntityTest {
       EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
       EdmEntityType edmEntityType = edmEntitySet.getEntityType();
 
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, null);
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
       jpaEntity.create(ODataEntryMockUtil.mockODataEntry(JPATypeMock.ENTITY_NAME));
     } catch (ODataJPARuntimeException e) {
       fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
@@ -84,10 +91,17 @@ public class JPAEntityTest {
     } catch (EdmException 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);
     }
     JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
     assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
     assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
+    assertEquals(ODataEntryMockUtil.VALUE_C.charAt(0), jpaTypeMock.getMC());
+    assertEquals(ODataEntryMockUtil.VALUE_CARRAY, new String(jpaTypeMock.getMCArray()));
+    assertEquals(ODataEntryMockUtil.VALUE_CHAR, jpaTypeMock.getMChar().toString());
+    assertEquals(ODataEntryMockUtil.VALUE_CHARARRAY, JPAEntityParser.toString(jpaTypeMock.getMCharArray()));
     assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
   }
 
@@ -97,7 +111,7 @@ public class JPAEntityTest {
       EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
       EdmEntityType edmEntityType = edmEntitySet.getEntityType();
 
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, ODataJPAContextMock.mockODataJPAContext());
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
       jpaEntity.create(ODataEntryMockUtil.mockODataEntryWithInline(JPATypeMock.ENTITY_NAME));
     } catch (ODataJPARuntimeException e) {
       fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
@@ -105,6 +119,9 @@ public class JPAEntityTest {
     } catch (EdmException 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);
     }
     JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
     assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
@@ -124,7 +141,7 @@ public class JPAEntityTest {
       EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
       EdmEntityType edmEntityType = edmEntitySet.getEntityType();
 
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, null);
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
       jpaEntity.create(ODataEntryMockUtil.mockODataEntryProperties(JPATypeMock.ENTITY_NAME));
     } catch (ODataJPARuntimeException e) {
       fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage()
@@ -132,6 +149,9 @@ public class JPAEntityTest {
     } catch (EdmException 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);
     }
     JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
     assertEquals(jpaTypeMock.getMInt(), ODataEntryMockUtil.VALUE_MINT);
@@ -140,12 +160,33 @@ public class JPAEntityTest {
   }
 
   @Test
+  public void testCreateODataEntryPropertyWithOutCallBack() {
+    try {
+      EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
+      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContextWithoutCallBack());
+      jpaEntity.create(ODataEntryMockUtil.mockODataEntryProperties(JPATypeMock.ENTITY_NAME));
+    } catch (ODataJPARuntimeException e) {
+      assertEquals(ODataJPARuntimeException.ERROR_JPA_BLOB_NULL.getKey(), e.getMessageReference().getKey());
+      return;
+    } catch (EdmException 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);
+    }
+    fail(ODataJPATestConstants.EXCEPTION_EXPECTED);
+  }
+
+  @Test
   public void testUpdateODataEntry() {
     try {
       EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
       EdmEntityType edmEntityType = edmEntitySet.getEntityType();
 
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, ODataJPAContextMock.mockODataJPAContext());
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
       JPATypeMock jpaTypeMock = new JPATypeMock();
       jpaEntity.setJPAEntity(jpaTypeMock);
       jpaEntity.update(ODataEntryMockUtil.mockODataEntry(JPATypeMock.ENTITY_NAME));
@@ -155,6 +196,9 @@ public class JPAEntityTest {
     } catch (EdmException 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);
     }
     JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
     assertEquals(jpaTypeMock.getMInt(), 0);// Key should not be changed
@@ -168,7 +212,7 @@ public class JPAEntityTest {
       EdmEntitySet edmEntitySet = EdmMockUtilV2.mockEdmEntitySet(JPATypeMock.ENTITY_NAME, false);
       EdmEntityType edmEntityType = edmEntitySet.getEntityType();
 
-      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, null);
+      jpaEntity = new JPAEntity(edmEntityType, edmEntitySet, mockODataJPAContext());
       JPATypeMock jpaTypeMock = new JPATypeMock();
       jpaEntity.setJPAEntity(jpaTypeMock);
       jpaEntity.update(ODataEntryMockUtil.mockODataEntryProperties(JPATypeMock.ENTITY_NAME));
@@ -178,10 +222,25 @@ public class JPAEntityTest {
     } catch (EdmException 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);
     }
     JPATypeMock jpaTypeMock = (JPATypeMock) jpaEntity.getJPAEntity();
     assertEquals(jpaTypeMock.getMInt(), 0);// Key should not be changed
     assertEquals(jpaTypeMock.getMString(), ODataEntryMockUtil.VALUE_MSTRING);
     assertTrue(jpaTypeMock.getMDateTime().equals(ODataEntryMockUtil.VALUE_DATE_TIME));
   }
+
+  private ODataJPAContext mockODataJPAContext() throws ODataException {
+    ODataContext context = new ODataContextMock().mock();
+    ODataJPAContext jpaContext = ODataJPAContextMock.mockODataJPAContext(context);
+    return jpaContext;
+  }
+
+  private ODataJPAContext mockODataJPAContextWithoutCallBack() throws ODataException {
+    ODataContext context = new ODataContextMock().mockWithoutOnJPAWriteContent();
+    ODataJPAContext jpaContext = ODataJPAContextMock.mockODataJPAContext(context);
+    return jpaContext;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
index d4a691e..3bc3f14 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
@@ -41,6 +41,20 @@ public class ODataContextMock {
     ODataContext context = EasyMock.createMock(ODataContext.class);
     EasyMock.expect(context.getService()).andReturn(odataService).anyTimes();
     EasyMock.expect(context.getPathInfo()).andReturn(pathInfo).anyTimes();
+    ODataJPAServiceFactoryMock mockServiceFactory = new ODataJPAServiceFactoryMock(context);
+    mockServiceFactory.initializeODataJPAContext();
+    EasyMock.expect(context.getServiceFactory()).andReturn(mockServiceFactory).anyTimes();
+    EasyMock.replay(context);
+    return context;
+  }
+
+  public ODataContext mockWithoutOnJPAWriteContent() throws ODataException {
+    ODataContext context = EasyMock.createMock(ODataContext.class);
+    EasyMock.expect(context.getService()).andReturn(odataService).anyTimes();
+    EasyMock.expect(context.getPathInfo()).andReturn(pathInfo).anyTimes();
+    ODataJPAServiceFactoryMock mockServiceFactory = new ODataJPAServiceFactoryMock(context);
+    mockServiceFactory.initializeODataJPAContextX();
+    EasyMock.expect(context.getServiceFactory()).andReturn(mockServiceFactory).anyTimes();
     EasyMock.replay(context);
     return context;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
index 17464a4..433f784 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
@@ -49,6 +49,7 @@ public abstract class ODataJPAContextMock {
     ODataJPAContext odataJPAContext = EasyMock.createMock(ODataJPAContext.class);
     EasyMock.expect(odataJPAContext.getPersistenceUnitName()).andStubReturn(NAMESPACE);
     EasyMock.expect(odataJPAContext.getEntityManagerFactory()).andReturn(mockEntityManagerFactory());
+    EasyMock.expect(odataJPAContext.getEntityManager()).andReturn(mockEntityManager());
     EasyMock.expect(odataJPAContext.getJPAEdmMappingModel()).andReturn(MAPPING_MODEL);
     EasyMock.expect(odataJPAContext.getJPAEdmExtension()).andReturn(null);
     EasyMock.expect(odataJPAContext.getDefaultNaming()).andReturn(true);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAServiceFactoryMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAServiceFactoryMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAServiceFactoryMock.java
new file mode 100644
index 0000000..8535fe4
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAServiceFactoryMock.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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 org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+
+public class ODataJPAServiceFactoryMock extends ODataJPAServiceFactory {
+  private ODataContext context = null;
+
+  public ODataJPAServiceFactoryMock(ODataContext context) {
+    this.context = context;
+  }
+
+  @Override
+  public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException {
+    ODataJPAContext oDataJPAContext = null;
+    oDataJPAContext = ODataJPAContextMock.mockODataJPAContext(this.context);
+    setOnWriteJPAContent(new OnJPAWriteContentMock());
+    return oDataJPAContext;
+  }
+
+  public ODataJPAContext initializeODataJPAContextX() throws ODataJPARuntimeException {
+    ODataJPAContext oDataJPAContext = null;
+    oDataJPAContext = ODataJPAContextMock.mockODataJPAContext(this.context);
+    setOnWriteJPAContent(null);
+    return oDataJPAContext;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/OnJPAWriteContentMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/OnJPAWriteContentMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/OnJPAWriteContentMock.java
new file mode 100644
index 0000000..6a59361
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/OnJPAWriteContentMock.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+import javax.sql.rowset.serial.SerialException;
+
+import org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+
+public class OnJPAWriteContentMock implements OnJPAWriteContent {
+
+  @Override
+  public Blob getJPABlob(byte[] binaryData) throws ODataJPARuntimeException {
+    try {
+      return new SerialBlob(binaryData);
+    } catch (SerialException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (SQLException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    }
+    return null;
+  }
+
+  @Override
+  public Clob getJPAClob(char[] characterData) throws ODataJPARuntimeException {
+    try {
+      return new SerialClob(characterData);
+    } catch (SerialException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    } catch (SQLException e) {
+      ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+    }
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/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 a15fbc1..095d7e1 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
@@ -18,6 +18,8 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.jpa.processor.core.mock.data;
 
+import java.sql.Blob;
+import java.sql.Clob;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
@@ -87,6 +89,18 @@ public class EdmMockUtilV2 {
           mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MSTRING)).anyTimes();
       EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MDATETIME)).andReturn(
           mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MDATETIME)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MBLOB)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MBLOB)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_CLOB)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_CLOB)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MC)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MC)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCARRAY)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCARRAY)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCHAR)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCHAR)).anyTimes();
+      EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCHARARRAY)).andReturn(
+          mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCHARARRAY)).anyTimes();
       EasyMock.expect(entityType.getProperty(JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)).andReturn(
           mockEdmProperty(entityName, JPATypeMock.PROPERTY_NAME_MCOMPLEXTYPE)).anyTimes();
       EasyMock.expect(entityType.getProperty(JPATypeMock.NAVIGATION_PROPERTY_X)).andReturn(
@@ -137,6 +151,12 @@ public class EdmMockUtilV2 {
       propertyNames.add(JPATypeMock.PROPERTY_NAME_MINT);
       propertyNames.add(JPATypeMock.PROPERTY_NAME_MDATETIME);
       propertyNames.add(JPATypeMock.PROPERTY_NAME_MSTRING);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MBLOB);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_CLOB);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MC);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MCARRAY);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MCHAR);
+      propertyNames.add(JPATypeMock.PROPERTY_NAME_MCHARARRAY);
     } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
       propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MLONG);
       propertyNames.add(JPARelatedTypeMock.PROPERTY_NAME_MBYTE);
@@ -226,6 +246,12 @@ public class EdmMockUtilV2 {
     if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MINT) ||
         propertyName.equals(JPATypeMock.PROPERTY_NAME_MSTRING) ||
         propertyName.equals(JPATypeMock.PROPERTY_NAME_MDATETIME) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MBLOB) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_CLOB) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCARRAY) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MC) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHAR) ||
+        propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHARARRAY) ||
         propertyName.equals(JPATypeMock.JPATypeEmbeddableMock.PROPERTY_NAME_MSHORT) ||
         propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MFLOAT) ||
         propertyName.equals(JPATypeMock.JPATypeEmbeddableMock2.PROPERTY_NAME_MUUID) ||
@@ -237,6 +263,18 @@ public class EdmMockUtilV2 {
       EdmSimpleType edmType = EasyMock.createMock(EdmSimpleType.class);
       EasyMock.expect(edmProperty.getType()).andReturn(edmType).anyTimes();
       EasyMock.expect(edmType.getKind()).andReturn(EdmTypeKind.SIMPLE).anyTimes();
+      if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MSTRING) ||
+          propertyName.equals(JPATypeMock.PROPERTY_NAME_MCARRAY) ||
+          propertyName.equals(JPATypeMock.PROPERTY_NAME_MC) ||
+          propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHAR) ||
+          propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHARARRAY)) {
+        EasyMock.<Class<?>> expect(edmType.getDefaultType()).andReturn(String.class).anyTimes();
+      } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MBLOB)) {
+        EasyMock.<Class<?>> expect(edmType.getDefaultType()).andReturn(Blob.class).anyTimes();
+      } else {
+        EasyMock.<Class<?>> expect(edmType.getDefaultType()).andReturn(Integer.class).anyTimes();
+      }
+
       EasyMock.expect(edmType.isCompatible(EasyMock.isA(EdmSimpleType.class))).andReturn(true).anyTimes();
       EasyMock.replay(edmType);
       EasyMock.expect(edmProperty.getName()).andReturn(propertyName).anyTimes();
@@ -311,6 +349,24 @@ public class EdmMockUtilV2 {
     } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MSTRING)) {
       mapping.setJPAType(String.class);
       ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MSTRING);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MBLOB)) {
+      mapping.setJPAType(Blob.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MBLOB);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_CLOB)) {
+      mapping.setJPAType(Clob.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_CLOB);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MC)) {
+      mapping.setJPAType(char.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MC);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCARRAY)) {
+      mapping.setJPAType(char[].class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCARRAY);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHAR)) {
+      mapping.setJPAType(Character.class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCHAR);
+    } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MCHARARRAY)) {
+      mapping.setJPAType(Character[].class);
+      ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MCHARARRAY);
     } else if (propertyName.equals(JPATypeMock.PROPERTY_NAME_MDATETIME)) {
       mapping.setJPAType(Calendar.class);
       ((Mapping) mapping).setInternalName(JPATypeMock.PROPERTY_NAME_MDATETIME);
@@ -344,5 +400,4 @@ public class EdmMockUtilV2 {
     }
     return mapping;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java
index 9242df9..be1475c 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/JPATypeMock.java
@@ -18,6 +18,8 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.jpa.processor.core.mock.data;
 
+import java.sql.Blob;
+import java.sql.Clob;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
@@ -30,6 +32,12 @@ public class JPATypeMock {
   public static final String PROPERTY_NAME_MINT = "mInt";
   public static final String PROPERTY_NAME_MSTRING = "mString";
   public static final String PROPERTY_NAME_MDATETIME = "mDateTime";
+  public static final String PROPERTY_NAME_MBLOB = "mBlob";
+  public static final String PROPERTY_NAME_CLOB = "mClob";
+  public static final String PROPERTY_NAME_MCHAR = "mChar";
+  public static final String PROPERTY_NAME_MCHARARRAY = "mCharArray";
+  public static final String PROPERTY_NAME_MC = "mC";
+  public static final String PROPERTY_NAME_MCARRAY = "mCArray";
   public static final String PROPERTY_NAME_MKEY = "key";
   public static final String PROPERTY_NAME_MCOMPLEXTYPE = "complexType";
 
@@ -41,6 +49,53 @@ public class JPATypeMock {
   private int mInt;
   private String mString;
   private Calendar mDateTime;
+  private Blob mBlob;
+  private Clob mClob;
+  private char mC;
+  private char[] mCArray;
+  private Character mChar;
+  private Character[] mCharArray;
+
+  public Clob getMClob() {
+    return mClob;
+  }
+
+  public void setMClob(Clob mClob) {
+    this.mClob = mClob;
+  }
+
+  public char getMC() {
+    return mC;
+  }
+
+  public void setMC(char mC) {
+    this.mC = mC;
+  }
+
+  public char[] getMCArray() {
+    return mCArray;
+  }
+
+  public void setMCArray(char[] mCArray) {
+    this.mCArray = mCArray;
+  }
+
+  public Character getMChar() {
+    return mChar;
+  }
+
+  public void setMChar(Character mChar) {
+    this.mChar = mChar;
+  }
+
+  public Character[] getMCharArray() {
+    return mCharArray;
+  }
+
+  public void setMCharArray(Character[] mCharArray) {
+    this.mCharArray = mCharArray;
+  }
+
   private JPARelatedTypeMock mRelatedEntity;
   private List<JPARelatedTypeMock> mRelatedEntities = new ArrayList<JPATypeMock.JPARelatedTypeMock>();
 
@@ -100,6 +155,14 @@ public class JPATypeMock {
     this.complexType = complexType;
   }
 
+  public Blob getMBlob() {
+    return mBlob;
+  }
+
+  public void setMBlob(Blob mBlob) {
+    this.mBlob = mBlob;
+  }
+
   /* ========================================================================= */
   public static class JPATypeEmbeddableMock {
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java
index 27ac4ea..13e1f05 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/ODataEntryMockUtil.java
@@ -38,11 +38,17 @@ public class ODataEntryMockUtil {
 
   public static final int VALUE_MINT = 20;
   public static Calendar VALUE_DATE_TIME = null;
+  public static byte[] VALUE_BLOB = null;
+  public static final String VALUE_CLOB = "ABC";
+  public static final String VALUE_C = "D";
+  public static final String VALUE_CARRAY = "EFG";
+  public static final String VALUE_CHAR = "I";
+  public static final String VALUE_CHARARRAY = "LMN";
   public static final String VALUE_MSTRING = "Mock";
   public static final long VALUE_MLONG = 1234567890L;
   public static final double VALUE_MDOUBLE = 20.12;
   public static final byte VALUE_MBYTE = 0XA;
-  public static final byte[] VALUE_MBYTEARRAY = { 0XA, 0XB };
+  public static final byte[] VALUE_MBYTEARRAY = new byte[] { 0XA, 0XB };
   public static final float VALUE_MFLOAT = 2.00F;
   public static final UUID VALUE_UUID = UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d");
   public static final short VALUE_SHORT = 2;
@@ -76,6 +82,14 @@ public class ODataEntryMockUtil {
       VALUE_DATE_TIME.set(2013, 1, 1, 1, 1, 1);
       propertyMap.put(JPATypeMock.PROPERTY_NAME_MDATETIME, VALUE_DATE_TIME);
 
+      VALUE_BLOB = VALUE_MBYTEARRAY;
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MBLOB, VALUE_BLOB);
+
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_CLOB, VALUE_CLOB);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MC, VALUE_C);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MCARRAY, VALUE_CARRAY);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MCHAR, VALUE_CHAR);
+      propertyMap.put(JPATypeMock.PROPERTY_NAME_MCHARARRAY, VALUE_CHARARRAY);
       propertyMap.put(JPATypeMock.PROPERTY_NAME_MSTRING, VALUE_MSTRING);
     } else if (entityName.equals(JPARelatedTypeMock.ENTITY_NAME)) {
       propertyMap.put(JPARelatedTypeMock.PROPERTY_NAME_MLONG, VALUE_MLONG);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/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 c981b62..26d3b41 100644
--- a/odata2-jpa-processor/jpa-ref/pom.xml
+++ b/odata2-jpa-processor/jpa-ref/pom.xml
@@ -1,22 +1,14 @@
 <?xml version="1.0"?>
-<!--
-  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.
--->
+<!-- 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. -->
 <project
 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
 	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
@@ -32,7 +24,7 @@
 	<artifactId>olingo-odata2-jpa-processor-ref</artifactId>
 	<packaging>jar</packaging>
 	<name>${project.artifactId}</name>
-	
+
 	<build>
 		<plugins>
 			<plugin>
@@ -72,7 +64,7 @@
 			</plugin>
 		</plugins>
 	</build>
-	
+
 	<dependencies>
 		<!-- JPA Support -->
 		<dependency>
@@ -88,7 +80,7 @@
 		<dependency>
 			<groupId>org.hsqldb</groupId>
 			<artifactId>hsqldb</artifactId>
-			<version>1.8.0.10</version>
+			<version>2.3.2</version>
 		</dependency>
 
 		<!-- OData Annotation Support -->
@@ -97,7 +89,7 @@
 			<artifactId>olingo-odata2-api-annotation</artifactId>
 			<version>${project.version}</version>
 		</dependency>
-		
+
 		<!-- JUnits -->
 		<dependency>
 			<groupId>junit</groupId>

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/BlobToByteConverter.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/BlobToByteConverter.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/BlobToByteConverter.java
new file mode 100644
index 0000000..8e9c6c2
--- /dev/null
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/converter/BlobToByteConverter.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.InputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+
+import org.hsqldb.jdbc.JDBCBlob;
+
+@Converter(autoApply = true)
+public class BlobToByteConverter implements AttributeConverter<Blob, byte[]> {
+
+  @Override
+  public byte[] convertToDatabaseColumn(Blob arg0) {
+    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+    InputStream is;
+    try {
+      is = arg0.getBinaryStream();
+      int b;
+      b = is.read();
+      while (b != -1) {
+        buffer.write(b);
+        b = is.read();
+      }
+    } catch (SQLException e) {
+      e.printStackTrace();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    return buffer.toByteArray();
+  }
+
+  @Override
+  public Blob convertToEntityAttribute(byte[] arg0) {
+    try {
+      return new JDBCBlob(arg0);
+    } catch (SQLException e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/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 c4ca423..83483de 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
@@ -18,20 +18,28 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.jpa.processor.ref.model;
 
+import java.sql.Blob;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
 import javax.persistence.Column;
+import javax.persistence.Convert;
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
 import javax.persistence.ManyToMany;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
 
+import org.eclipse.persistence.annotations.Converter;
+
 @Entity
 @Table(name = "T_MATERIAL")
+@Converter(
+    name = "BlobToByteConverter",
+    converterClass = org.apache.olingo.odata2.jpa.processor.ref.converter.BlobToByteConverter.class)
 public class Material {
 
   public Material() {}
@@ -57,6 +65,19 @@ 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)
+  private Blob materialImage;
+
+  public Blob getMaterialImage() {
+    return materialImage;
+  }
+
+  public void setMaterialImage(Blob materialImage) {
+    this.materialImage = materialImage;
+  }
+
   @ManyToMany
   private List<Store> stores = new ArrayList<Store>();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/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 4a93509..5691dca 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
@@ -18,25 +18,29 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.jpa.processor.ref.model;
 
+import java.sql.Clob;
 import java.util.Calendar;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.IdClass;
 import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 
 @Entity
+@IdClass(value = NoteKey.class)
 @Table(name = "T_NOTE")
 public class Note {
 
   public Note() {}
 
   public Note(final Calendar creationTime, final Calendar creationDate, final String createdBy,
-      final String text) {
+      final Clob text) {
     super();
     this.creationTime = creationTime;
     this.creationDate = creationDate;
@@ -56,7 +60,8 @@ public class Note {
   private String createdBy;
 
   @Column
-  private String text;
+  @Lob
+  private Clob text;
 
   @Column(name = "SO_ID")
   private long soId;
@@ -89,11 +94,11 @@ public class Note {
     this.createdBy = createdBy;
   }
 
-  public String getText() {
+  public Clob getText() {
     return text;
   }
 
-  public void setText(final String text) {
+  public void setText(final Clob text) {
     this.text = text;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/NoteKey.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/NoteKey.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/NoteKey.java
new file mode 100644
index 0000000..69309d6
--- /dev/null
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/NoteKey.java
@@ -0,0 +1,65 @@
+package org.apache.olingo.odata2.jpa.processor.ref.model;
+
+import java.io.Serializable;
+import java.util.Calendar;
+
+public class NoteKey implements Serializable {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 1L;
+
+  public Calendar getCreationTime() {
+    return creationTime;
+  }
+
+  public void setCreationTime(Calendar creationTime) {
+    this.creationTime = creationTime;
+  }
+
+  public Calendar getCreationDate() {
+    return creationDate;
+  }
+
+  public void setCreationDate(Calendar creationDate) {
+    this.creationDate = creationDate;
+  }
+
+  public String getCreatedBy() {
+    return createdBy;
+  }
+
+  public void setCreatedBy(String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  @Override
+  public int hashCode() {
+    return creationTime.hashCode() + creationDate.hashCode() + createdBy.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof Note) {
+      Note note = (Note) obj;
+
+      if (!note.getCreatedBy().equals(this.getCreatedBy())) {
+        return false;
+      }
+      if (!note.getCreationDate().equals(this.getCreationDate())) {
+        return false;
+      }
+      if (!note.getCreationTime().equals(this.getCreationTime())) {
+        return false;
+      }
+      return true;
+    }
+    return false;
+  }
+
+  private Calendar creationTime;
+  private Calendar creationDate;
+  private String createdBy;
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ba0ff6be/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 29e5007..5bbfcf4 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
@@ -22,6 +22,10 @@
 		<class>org.apache.olingo.odata2.jpa.processor.ref.model.Customer</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.converter.BlobToByteConverter</class>
 		<properties>
 			<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
 			<property name="javax.persistence.jdbc.url"


Mime
View raw message