2011-06-20 56 views
2

欣赏与此有关的帮助。到目前为止,我已经花了数小时。如何通过Hibernate将图像保存到SQLite数据库?

我一直在试图弄清楚如何通过Hibernate在Sqlite数据库中存储图像,但是会得到下面的异常。正如异常消息所说,我的SQLite JDBC驱动程序不支持setBinaryStream。我已经试过sqlitejdbc-v056和xerial sqlite-jdbc-3.7.2罐子。

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) 

我已经看到了在不同的地方这个讨论,并从其他Q &一个领域,我发现setBytes应该用来代替的setBinaryStream为一个PreparedStatement。但是对我而言,所有事情都是通过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) 

我想存储的图像被放在一个关联表单独的表,其余地方的实体正在被保存。我不明白它是如何成为代理的,因为它是一个新的对象实例,第一次通过会导致ClassCastException的session.save()被持久化。

我使用一个字节数组来保存我的Java对象中的图像数据,使用其他人的代码(在论坛中找到)在BufferedImage和byte []之间进行转换。

所以我想我最终的问题是“是否有通过Hibernate的解决方案,或者我必须自己使用PreparedStatement并绕过Hibernate?”

我是一个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(); 
} 

回答

0

附加的sqlite的JDBC驱动程序的补丁在这个discussion,其中包括实施setBinaryStream。

相关问题