如何通过 Hibernate 将图像保存到 SQLite 数据库?
感谢对此的帮助。到目前为止我已经花了几个小时了。
我一直试图弄清楚如何通过 Hibernate 将图像存储在 Sqlite 数据库中,但出现下面的异常。正如异常消息所示,我的 SQLite JDBC 驱动程序不支持 setBinaryStream。我尝试过 sqlitejdbc-v056 和 xerial sqlite-jdbc-3.7.2 jar。
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)
我在不同的地方看到过这个讨论,并且从其他问答区域我发现对于PreparedStatement应该使用setBytes而不是setBinaryStream。然而对我来说,一切都是通过 Hibernate 发生的,而不是由我直接声明的。我还没有找到涉及 Hibernate 的解决方案。
我的映射文件为图像列设置 type="blob"。如果我将其设置为“二进制”,如某个论坛中提到的那样,我会得到此异常:
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)
我尝试存储的图像将被放入与保存实体其余部分的表分开的关联表中。我不明白它如何成为代理,因为它是第一次通过 session.save() 持久保存的新对象实例,这会导致 ClassCastException。
我使用字节数组来保存 java 对象中的图像数据,使用其他人的代码(在论坛中找到)在 BufferedImage 和 byte[] 之间进行转换。
所以我想我的最终问题是“是否有通过 Hibernate 的解决方案,或者我必须自己使用PreparedStatement 并绕过 Hibernate?”
我是一个冬眠新手。
表创建语句:
create TABLE images (image_id INTEGER PRIMARY KEY AUTOINCREMENT, image BLOB not null);
Hibernate 映射:
<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();
}
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论