Using a BLOB data type in a CMP Enity Bean

I got an email from a customer who wanted to use BLOB data type in their CMP entity bean. In this blog, I will provide an example and will discuss how can you develop your CMP EJBs to use a BLOB database type.

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.



About the author

Debu Panda [email protected]
Blog: http://radio.weblogs.com/0135826

I'm Debu Panda ([email protected]) and I'm the Product Manager responsible for EJB Container in the Oracle Application Server development team. I've around 13 years of experience in IT mainly in the Database and Application Server technologies. I've authored articles in several journals and presented in several conferences.

Dig Deeper on DevOps-driven, cloud-native app development