Hibernate 4.2.2 create blob from unknown-length input stream

廉价感情. 提交于 2019-12-05 04:53:50

Here is what i'm using now

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

Try passing in the InputStream and a length of -1:

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

This works with SQL Server 2008. It seems that Hibernate passes this value directly to the JDBC driver, so this may or may not work depending on your database driver.

Note: If I pass in the incorrect stream length (including 0), I will get a DataException from Hibernate (from the driver: "com.microsoft.sqlserver.jdbc.SQLServerException: The stream value is not the specified length. The specified length was 10, the actual length is 13."). With a length of -1, it always works without complaining, and the data is saved successfully to the database.

Workaround could be to save input stream to a file then to read the file into blob.

I understand my answer is a little different from your question. But this may help others who land here. For my requirement, i am getting the absolute file path as the input to create a blob. If you too have a similar requirement, you can use the below snippet.

Session session = sessionFactory.getCurrentSession();
File file = new File(filePath);
Blob blob = Hibernate.getLobCreator(session).createBlob(new FileInputStream(file), file.length());

file.length() will give you the length of the file.

change the save method in Dao as below

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

I think, it's a goog solution, if you convert the InputStream to byte array, so you can use the createBlob method, that accepts a byte array instead of an InputStream and the length as parameter. For the converting you can use the IOUtils from the Apache Commons IO.

Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(IOUtils.toByteArray(stream)); 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!