2011-06-20 210 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。

相關問題