Appreciate help with this. I've spent hours at it so far.
I have been trying to figure out how to store an image in an Sqlite database via Hibernate, but get the exception below. As the exception message says, my SQLite JDBC driver does not support setBinaryStream. I have tried sqlitejdbc-v056 and xerial sqlite-jdbc-3.7.2 jars.
Caused by: java.sql.SQLException: not implemented by SQLite JDBC driver
at org.sqlite.Unused.unused(Unused.java:29)
at org.sqlite.Unused.setBinaryStream(Unused.java:60)
at org.hibernate.type.BlobType.set(BlobType.java:99)
I've seen this discussed in various places, and from other Q&A areas I found that setBytes should be used instead of setBinaryStream for a PreparedStatement. However for me, everything is happening via Hibernate, not by any direct statements by me. I have not found a solution involving Hibernate yet.
My mapping file sets type="blob" for the image column. If I set it to "binary" as was mentioned in a forum somewhere, I get this exception:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: $Proxy2
at org.hibernate.type.BinaryType.toInternalFormat(BinaryType.java:38)
at org.hibernate.type.AbstractBynaryType.deepCopyNotNull(AbstractBynaryType.java:172)
The image I am trying to store is to be put in an association table separate to the table where the rest of the entity is being saved. I do not see how it can be a proxy, because it is a new object instance being persisted for the first time via session.save() which results in the ClassCastException.
I use a byte array for holding the image data in my java object, using code from others (found in forums) to convert between BufferedImage and byte[].
So I suppose the ultimate question I have is "is there a solution via Hibernate, or must I use a PreparedStatement myself and bypass Hibernate?"
I am a hibernate newbie.
Table create statement:
create TABLE images (image_id INTEGER PRIMARY KEY AUTOINCREMENT, image BLOB not null);
Hibernate mapping:
<class name="ImageImpl" table="images">
<id name="id" column="image_id">
<generator class="identity"/>
</id>
<property name="imageBlob" column="image" type="blob"/>
</class>
Java:
private byte[] m_imageBytes;
// for use by hibernate
@SuppressWarnings("unused")
protected Blob getImageBlob ()
{ return Hibernate.createBlob(m_imageBytes); }
// for use by hibernate
@SuppressWarnings("unused")
private void setImageBlob (Blob blob)
{ m_imageBytes = toByteArray(blob); }
private byte[] toByteArray (Blob blob)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
return toByteArrayImpl(blob, baos);
}
catch (SQLException e)
{
throw new RuntimeException(e);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
finally
{
if (baos != null)
{
try
{
baos.close();
}
catch (IOException ex)
{}
}
}
}
private byte[] toByteArrayImpl (Blob fromBlob, ByteArrayOutputStream baos)
throws SQLException, IOException
{
byte[] buf = new byte[4000];
InputStream is = fromBlob.getBinaryStream();
try
{
for (;;)
{
int dataSize = is.read(buf);
if (dataSize == -1)
break;
baos.write(buf, 0, dataSize);
}
}
finally
{
if (is != null)
{
try
{
is.close();
}
catch (IOException ex)
{}
}
}
return baos.toByteArray();
}