Как сохранить изображение в базе данных SQLite через Hibernate? - PullRequest
2 голосов
/ 20 июня 2011

Ценю помощь в этом. Я провел часы в этом до сих пор.

Я пытался выяснить, как сохранить изображение в базе данных Sqlite через Hibernate, но получил исключение ниже. Как говорится в сообщении об исключении, мой драйвер 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)

Я видел, что это обсуждалось в разных местах, и из других областей вопросов и ответов я обнаружил, что 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)

Образ, который я пытаюсь сохранить, должен быть помещен в таблицу ассоциации, отдельную от таблицы, в которой сохраняется остальная часть объекта. Я не понимаю, как это может быть прокси, потому что это новый экземпляр объекта, который сохраняется впервые через session.save (), что приводит к исключению ClassCastException.

Я использую байтовый массив для хранения данных изображения в моем java-объекте, используя код других пользователей (найденный на форумах) для преобразования между BufferedImage и byte [].

Итак, я полагаю, что последний вопрос, который у меня возник, заключается в том, «есть ли решение через Hibernate, или я должен сам использовать PreparedStatement и обойти Hibernate?»

Я спящий новичок.

Оператор создания таблицы:

create TABLE images (image_id INTEGER PRIMARY KEY AUTOINCREMENT, image BLOB not null);

Отображение гибернации:

<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();
}

1 Ответ

0 голосов
/ 22 октября 2011

В этом обсуждении прилагается патч для драйвера sqlite jdbc, который включает реализацию setBinaryStream.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...