Hibernate 4.2.2 создание blob из входного потока неизвестной длины

Привет я хочу создать blob в спящем режиме из inputstream, но я не знаю длину потока.

Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(stream, length)

Как я могу упаковывать шарик, не зная длины потока?

EDIT1

в старых версиях hibernate это было возможно

http://viralpatel.net/blogs/tutorial-save-get-blob-object-spring-3-mvc-hibernate/

блоб блоб = Зимовать.createBlob (файл.getInputStream());

EDIT2

хорошо, но у него была багги реализация

вернуть новый SerializableBlob (новый BlobImpl (stream, stream.available () ));

поток.доступен не реальный размер

редактировать 3

пробовал

session.doWork(new Work() {
            @Override
            public void execute(Connection conn) throws SQLException {
            LargeObjectManager lobj = ((org.postgresql.PGConnection) conn).getLargeObjectAPI();

но conn-это просто NewProxyConnection от c3p0.

6 ответов


вот что я использую сейчас

Session currentSession = getSessionFactory().getCurrentSession();
Blob blob = Hibernate.getLobCreator(currentSession).createBlob(new byte[0]);
OutputStream setBinaryStream = blob.setBinaryStream(1);
Utils.fastChannelCopy(input, setBinaryStream);
setBinaryStream.close();

попробуйте передать InputStream и длину -1:

session.getLobHelper().createBlob(stream, -1);

это работает с SQL Server 2008. Похоже, что Hibernate передает это значение непосредственно драйверу JDBC, поэтому это может работать или не работать в зависимости от драйвера базы данных.

Примечание: Если я передам неправильную длину потока (включая 0), я получу исключение DataException из Hibernate (от драйвера: "com.Microsoft.от SQLServer.интерфейс jdbc.SQLServerException: значение потока не является указанной длиной. Этот указанная длина составила 10,фактическая-13."). При длине -1 Он всегда работает без жалоб, и данные успешно сохраняются в базе данных.


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


Я понимаю, что мой ответ немного отличается от вашего вопроса. Но это может помочь другим, кто высадится здесь. Для моего требования я получаю абсолютный путь к файлу в качестве входных данных для создания blob. Если у вас тоже есть подобное требование, вы можете использовать приведенный ниже фрагмент.

Session session = sessionFactory.getCurrentSession();
File file = new File(filePath);
Blob blob = Hibernate.getLobCreator(session).createBlob(new FileInputStream(file), file.length());
.length () даст вам длину файла.

измените метод save в Dao, как показано ниже

@Transactional
public void save(Document document, InputStream inputStream) throws IOException {
    Session session = sessionFactory.getCurrentSession();
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    int nRead;
    byte[] data = new byte[16384];

    while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, nRead);
    }

    buffer.flush();
    Blob blob = Hibernate.getLobCreator(session).createBlob(buffer.toByteArray());
    document.setContent(blob);
    session.save(document);
}

Я думаю, это решение goog, если вы преобразуете InputStream в массив байтов, поэтому вы можете использовать метод createBlob, который принимает массив байтов вместо InputStream и length в качестве параметра. Для преобразования вы можете использовать IOUtils из Apache Commons IO.

Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(IOUtils.toByteArray(stream));