I'm using user defined BinaryBlobType in my code and never had any problems with it until I recently upgraded to c3p0 version 8.5.1 from c3p0 version 8.4.5. Here is the code for BinaryBlobType
Code:
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.Blob;
import java.io.*;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.UserType;
public class BinaryBlobType implements UserType
{
public int[] sqlTypes()
{
return new int[] { Types.BLOB };
}
public Class returnedClass()
{
return byte[].class;
}
public boolean equals(Object x, Object y)
{
return (x == y)
|| (x != null
&& y != null
&& java.util.Arrays.equals((byte[]) x, (byte[]) y));
}
public Object deepCopy(Object value)
{
if (value == null) return null;
byte[] bytes = (byte[]) value;
byte[] result = new byte[bytes.length];
System.arraycopy(bytes, 0, result, 0, bytes.length);
return result;
}
public boolean isMutable()
{
return true;
}
//Modified code
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException
{
System.out.println("PreparedStatement is of type: " + st.getClass().getName());
if(st instanceof com.mchange.v2.sql.filter.FilterPreparedStatement &&
((com.mchange.v2.sql.filter.FilterPreparedStatement) st).getInner()
instanceof oracle.jdbc.OraclePreparedStatement)
{
oracle.sql.BLOB blob = oracle.sql.BLOB.createTemporary(
st.getConnection().getMetaData().getConnection(), false, oracle.sql.BLOB.DURATION_SESSION);
//register temporary blob for future cleanup
HibernateUtil.registerTempBLOB(blob);
blob.open(oracle.sql.BLOB.MODE_READWRITE);
OutputStream out = blob.getBinaryOutputStream();
try
{
out.write((byte[])value);
out.flush();
out.close();
}
catch(IOException e)
{
throw new SQLException("failed write to blob" + e.getMessage());
}
blob.close();
((oracle.jdbc.OraclePreparedStatement)((com.mchange.v2.sql.filter.FilterPreparedStatement)st).getInner()).setBytes(index,
blob.getBytes(1, (int) blob.length()));
}
else if( st instanceof com.mchange.v2.c3p0.impl.NewProxyPreparedStatement )
{
com.mchange.v2.c3p0.impl.NewProxyPreparedStatement npc = (com.mchange.v2.c3p0.impl.NewProxyPreparedStatement) st;
if( ! ((npc.getConnection().getMetaData().getConnection()) instanceof oracle.jdbc.OracleConnection) )
throw new HibernateException(" connection not of type OracleConnection");
oracle.sql.BLOB blob = oracle.sql.BLOB.createTemporary(
(oracle.jdbc.OracleConnection) ((com.mchange.v2.c3p0.impl.NewProxyPreparedStatement) st).getConnection().getMetaData().getConnection(), false, oracle.sql.BLOB.DURATION_SESSION);
blob.open(oracle.sql.BLOB.MODE_READWRITE);
OutputStream out = blob.getBinaryOutputStream();
try
{
out.write((byte[])value);
out.flush();
out.close();
}
catch(IOException e)
{
throw new SQLException("failed write to blob" + e.getMessage());
}
blob.close();
((com.mchange.v2.c3p0.impl.NewProxyPreparedStatement) st).setBytes( index, blob.getBytes(1, (int) blob.length()));
}
else if (st instanceof oracle.jdbc.OraclePreparedStatement)
{
oracle.sql.BLOB blob =
oracle.sql.BLOB.createTemporary(st.getConnection(),
false,
oracle.sql.BLOB.DURATION_SESSION);
blob.open(oracle.sql.BLOB.MODE_READWRITE);
OutputStream out = blob.getBinaryOutputStream();
try
{
out.write((byte[]) value);
out.flush();
out.close();
}
catch (IOException e)
{
throw new SQLException("failed write to blob" + e.getMessage());
}
blob.close();
//((oracle.jdbc.OraclePreparedStatement) st).setBLOB( index, blob);
((oracle.jdbc.OraclePreparedStatement) st).setBytes( index, blob.getBytes(1, (int) blob.length()));
}
else
{
st.setBlob(index, Hibernate.createBlob((byte[]) value));
}
}
//and.. note the null check, oracle drivers return a null blob...
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException
{
final Blob blob = rs.getBlob(names[0]);
return blob != null?blob.getBytes(1, (int)blob.length()):null;
}
}
As you can see, there was a means to get a handle to OraclePreparedStatement and the connection type was of OracleConnection in c3p0 v. 8.4.5. But in version 8.5.1, from the NewProxyPreparedStatement object, I could not find a means to get the physical connection (OracleConnection) object nor the OraclePreparedStatement object. Does anybody know the solution to this problem.
I'm using Oracle 9i, hibernate 2.1.6 with c3p0 version 8.5.1.
Thanks in advance.