Inside Scoop on J2EE : Tips and tricks on J2EE and Oracle Application Server by Debu Panda
Updated: 11/18/2004; 5:19:21 PM.

 

Subscribe to "Inside Scoop on J2EE" in Radio UserLand.

Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.

 
 

Wednesday, August 11, 2004

 

I got an email from a customer who wanted to use BLOB data type in their CMP entity bean. They store images in BLOB data types in Oracle database and want to map their CMP entity bean field to a BLOB data type. Manipulation of CLOB and BLOB from J2EE applications is  a challenging task. However doing this from a CMP Entity Bean hides a lot of complexities of JDBC. In this blog, I will provide an example and will discuss how can you develop your CMP EJBs to use a BLOB database type.

 

In relational databases like Oracle, CLOB and BLOB column types are used to store large objects. BLOB stands for Binary Large Objects and this data type is used to store images, pictures, videos, etc. CLOB stands for Character Large Objects and can store large volumes of character-based data.

JDBC defines Java types java.sql.Clob and java.sql.Blob as the corresponding types for manipulating CLOB and BLOB types in the database. However these types cannot be used in Entity Beans because they are not Serializable. Hence you cannot define a field of type java.sql.Clob or java.sql.Blob in the CMP entity bean.

If you want to use a BLOB column in the database you have to declare a CMP field of byte[] in your entity bean and map this field to the database column of type BLOB.  For using CLOB column types in the database you have to use either types java.lang.String or char[] for the field types in the CMP entity bean.

 

An Entity bean example

 

In a company you may want to store pictures of your employees in database table for security purposes. Let us use an EmployeePicture entity bean as an example that manipulates pictures for employees. The EmployeePictureBean has two container managed fields empno, picture. The picture field is defined of type byte[].

The EmployeePicture entity bean is mapped to EMPPIC database table, the picture field is mapped to picture column of EMPPIC table and the picture column is defined to be of type BLOB.

 

The following is a code snippet from EmployeePictureBean.java

 

public abstract class EmployeePictureBean implements EntityBean
{
  ....
  public abstract byte[] getPicture();
  public abstract void setPicture(byte[] newPicture);
  public Long ejbCreate(Long empno, byte[] newPicture)
  {
    setEmpno(empno);
    setPicture(newPicture);
    return empno;
  }

  public void ejbPostCreate(Long empno, byte[] newPicture)
  {
  }
  ...
}

Let us assume that we are using OC4J 9.0.4 . We need to define the mapping of entity bean fields to tables and columns in the orion-ejb-jar.xml. If you are using any other J2EE container you need to define the O-R mapping in the respective vendor deployment descriptor. This shows the picture field in the EmployeePicture bean to be mapped to a BLOB column in OC4J:

 

<entity-deployment name="EmployeePicture" data-source="jdbc/OracleDS" table="EMPPIC">
  <primkey-mapping>
    <cmp-field-mapping name="empno" persistence-name="EMPNO" persistence-type="NUMBER(8)"/>
  </primkey-mapping>
  <cmp-field-mapping name="empno" persistence-name="EMPNO" persistence-type="NUMBER(8)"/>
  <cmp-field-mapping name="picture" persistence-name="PICTURE" persistence-type="BLOB"/>
</entity-deployment>

 

The Client:

 

There is nothing special in the client for CMP entity bean that manipulates a BLOB column. The only difference is reading the IMAGE FILEs using BufferedInputStream during update to the database and using OutputStream while retrieving from the database.

Here is how we read the image File and create the bean instance:

 

    // Locate and open the file

    File imgFile = new File(fileName);

    long imgFileSize= imgFile.length();

    // initialize the byte array

    byte byteValue[] = new byte[(int)imgFileSize];

    // Read the file into the byte array            

    InputStream is = new BufferedInputStream(new FileInputStream(imgFile));           

    int len = is.read(byteValue);

    //Add the byte to the entity bean field

    if(len!=imgFileSize)

    {

           System.out.println(“Read bytes did not equal file size on directory”);

    }

    else

    {

      EmployeePictureLocal employeePicture = empHome.create(empNo , byteValue);

     

 

Conclusion

 

You cannot directly map a java.sql.Blob field type in CMP entity bean to BLOB data type in database and use byte[] to manipulate BLOB data type. You have to remember that this is not an efficient approach if you are storing data that is very large (more than 25M) and probably consider alternatives.

 

The full code of this example may be downloaded from  http://www.oracle.com/technology/tech/java/oc4j/904/how_to/how-to-ejb-cmpblob.zip.

Update:

You have to note that earlier releases of Oracle JDBC THIN driver has limitation of streaming more than 4KB. So you have to use OCI driver if you want to store/retrieve more than 4KB if you are using a JDBC driver earlier than 10g. Oracle Application Server 10g does not have this limitation even if you are using an earlier version of THIN driver.

This was published as featured article in TSS

http://www.theserverside.com/blogs/showblog.tss?id=UsingBLOBDataType


11:51:17 AM    comment []

© Copyright 2004 Debu Panda.

PS: These are my own thoughts and not of my employer ..



Click here to visit the Radio UserLand website.
 


August 2004
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Jul   Sep