Author: mikedd
Date: Wed Jul 22 23:09:02 2009
New Revision: 796907

URL: http://svn.apache.org/viewvc?rev=796907&view=rev
Log:
OPENJPA-922: 
Allow DB2 to use setByteArrayInputStream instead of setBytes when needed.
Submitted by : B. J. Reed

Added:
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/ByteArrayHolder.java
   (with props)
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestByteArray.java
   (with props)
Modified:
    
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java

Modified: 
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java?rev=796907&r1=796906&r2=796907&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
 (original)
+++ 
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
 Wed Jul 22 23:09:02 2009
@@ -18,10 +18,13 @@
  */
 package org.apache.openjpa.jdbc.sql;
 
+import java.io.ByteArrayInputStream;
 import java.lang.reflect.Method;
+import java.sql.Blob;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
 import java.util.Arrays;
@@ -913,4 +916,60 @@
             super.setQueryTimeout(stmnt, timeout);
         }
     }
+
+    /**
+     * Set the given value as a parameter to the statement.
+     */
+    public void setBytes(PreparedStatement stmnt, int idx, byte[] val,
+        Column col)
+        throws SQLException {
+        // for DB2, if the column was defined as CHAR for BIT DATA, then
+        // we want to use the setBytes in stead of the setBinaryStream
+        if (useSetBytesForBlobs 
+                || (col.getTypeName() != null && 
col.getTypeName().contains("BIT DATA"))) {
+            stmnt.setBytes(idx, val);
+        } else {
+            setBinaryStream(stmnt, idx, new ByteArrayInputStream(val), 
val.length, col);
+        }
+    }
+
+    /**
+     * Convert the specified column of the SQL ResultSet to the proper
+     * java type.
+     */
+    public byte[] getBytes(ResultSet rs, int column)
+        throws SQLException {
+        if (useGetBytesForBlobs) {
+            return rs.getBytes(column);
+        }
+        if (useGetObjectForBlobs) {
+            return (byte[]) rs.getObject(column);
+        }
+
+        // At this point we don't have any idea if the DB2 column was defined 
as
+        //     a blob or if it was defined as CHAR for BIT DATA.
+        // First try as a blob, if that doesn't work, then try as CHAR for BIT 
DATA
+        // If that doesn't work, then go ahead and throw the first exception
+        try {
+            Blob blob = getBlob(rs, column);
+            if (blob == null) {
+                return null;
+            }
+            
+            int length = (int) blob.length();
+            if (length == 0) {
+                return null;
+            }
+            
+            return blob.getBytes(1, length);
+        }
+        catch (SQLException e) {
+            try {
+                return rs.getBytes(column);
+            }
+            catch (SQLException e2) {
+                throw e;                
+            }
+        }
+    }
 }

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/ByteArrayHolder.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/ByteArrayHolder.java?rev=796907&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/ByteArrayHolder.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/ByteArrayHolder.java
 Wed Jul 22 23:09:02 2009
@@ -0,0 +1,61 @@
+/*
+ * 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.openjpa.persistence.fields;
+
+import java.io.Serializable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+import static javax.persistence.GenerationType.IDENTITY;
+
+...@entity
+public class ByteArrayHolder implements Serializable {
+    @Id
+    @Column(name="TASK_ID")
+    @GeneratedValue(strategy=IDENTITY)
+    private int taskId;
+
+    @Column(columnDefinition="CHAR(16) FOR BIT DATA NOT NULL")  // type 1004 
size -1 should be size 0
+    //@Lob //type 1004 size -1 should be 1003
+    private byte[] tkiid;
+
+    private static final long serialVersionUID = 1L;
+
+    public ByteArrayHolder() {
+        super();
+    }
+
+    public int getTaskId() {
+        return this.taskId;
+    }
+
+    public void setTaskId(int taskId) {
+        this.taskId = taskId;
+    }
+
+    public byte[] getTkiid() {
+        return this.tkiid;
+    }
+
+    public void setTkiid(byte[] tkiid) {
+        this.tkiid = tkiid;
+    }
+}

Propchange: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/ByteArrayHolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestByteArray.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestByteArray.java?rev=796907&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestByteArray.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestByteArray.java
 Wed Jul 22 23:09:02 2009
@@ -0,0 +1,88 @@
+/*
+ * 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.openjpa.persistence.fields;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DB2Dictionary;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+
+/*
+ * This tests a particular kind of byte [] that is not a BLOB for DB2.  Don't 
need to
+ * do anything except return if we are using a different DB.
+ */
+public class TestByteArray extends SingleEMTestCase {
+    boolean runTest=false;
+    
+    public void setUp()  {
+        super.setUp();
+        OpenJPAEntityManagerFactorySPI ojpaEmf = 
(OpenJPAEntityManagerFactorySPI) emf;
+        JDBCConfiguration conf = (JDBCConfiguration) 
ojpaEmf.getConfiguration();
+        if (conf.getDBDictionaryInstance() instanceof DB2Dictionary) {
+            runTest = true;
+            super.setUp(ByteArrayHolder.class, CLEAR_TABLES);
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    public void testByteArray() {
+        if (! runTest) { 
+            // skip if not DB2 (from setup)
+            System.out.println("MDD skipping");
+            return;
+        }
+
+        EntityManager em = emf.createEntityManager();
+        EntityManager em2 = emf.createEntityManager();
+
+        byte[] ba =
+            new byte[] { (byte) 0xa0, (byte) 0x1b, (byte) 0x01, (byte) 0x1f,
+                (byte) 0x38, (byte) 0xcf, (byte) 0x67, (byte) 0x35,
+                (byte) 0x55, (byte) 0x43, (byte) 0xd9, (byte) 0xf6,
+                (byte) 0x71, (byte) 0x5e, (byte) 0x00, (byte) 0x00 };
+        ByteArrayHolder holder = new ByteArrayHolder();
+        holder.setTkiid(ba);
+        try {
+            em.getTransaction().begin();
+            em.persist(holder);
+            em.getTransaction().commit();
+        } catch(Throwable t) {
+            t.printStackTrace();
+            fail("Error: Task insert failed");
+        }
+
+        // verify that the get works
+        Query q = em2.createQuery("select e from ByteArrayHolder e");
+        List<ByteArrayHolder> elist = q.getResultList();
+        for (ByteArrayHolder e : elist) {
+            String baFromH = new String(e.getTkiid());
+            assertEquals(new String (ba), baFromH);
+        }
+        
+        // verify that it's still in the original EntityManager 
+        holder = em.find(ByteArrayHolder.class, holder.getTaskId());
+        String baFromH = new String(holder.getTkiid());
+        assertEquals(new String (ba), baFromH);
+    }
+}

Propchange: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fields/TestByteArray.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to