August 16, 2004
Using a BLOB data type in a CMP Entity Bean
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
debabrata.panda@oracle.com
Blog: http://radio.weblogs.com/0135826
I'm Debu Panda (debabrata.panda@oracle.com) 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.
|