Java Hibernate 4.2.2 从未知长度的输入流创建 blob

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19908279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 21:14:07  来源:igfitidea点击:

Hibernate 4.2.2 create blob from unknown-length input stream

javahibernatestreamblob

提问by wutzebaer

Hi i want to create a blob in hibernate from an inputstream, but i don't know the length of the stream.

嗨,我想从输入流在休眠中创建一个 blob,但我不知道流的长度。

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

how can i crate a blob without knowing the length of the stream?

我怎样才能在不知道流长度的情况下创建一个 blob?

EDIT1

编辑1

in older hibernate versions it was possible

在较旧的休眠版本中,这是可能的

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

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

Blob blob = Hibernate.createBlob(file.getInputStream());

Blob blob = Hibernate.createBlob(file.getInputStream());

EDIT2

编辑2

ok but it had an buggy implementation

好的,但它有一个错误的实现

return new SerializableBlob( new BlobImpl( stream, stream.available() ) );

return new SerializableBlob( new BlobImpl( stream, stream.available() ) );

stream.available isn't the real size

stream.available 不是真正的大小

EDIT 3

编辑 3

i tried

我试过

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

but conn is just a NewProxyConnection from c3p0.

但是 conn 只是来自 c3p0 的 NewProxyConnection。

采纳答案by wutzebaer

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

回答by zAlbee

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

尝试传入 InputStream 和 -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.

这适用于 SQL Server 2008。似乎 Hibernate 将此值直接传递给 JDBC 驱动程序,因此这可能会或可能不会起作用,具体取决于您的数据库驱动程序。

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.

注意:如果我传入不正确的流长度(包括 0),我将从 Hibernate 得到一个 DataException(来自驱动程序:“com.microsoft.sqlserver.jdbc.SQLServerException: The stream value is not the specified length. The specified length是 10,实际长度是 13。”)。长度为 -1 时,它始终可以正常工作,并且数据成功保存到数据库中。

回答by Uttesh Kumar

change the save method in Dao as below

更改 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);
}

回答by Predrag Spasojevic

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

解决方法可能是将输入流保存到文件中,然后将该文件读入 blob。

回答by rudrasiva86

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.

我知道我的回答和你的问题有点不同。但这可能会帮助其他登陆这里的人。根据我的要求,我将绝对文件路径作为创建 blob 的输入。如果您也有类似的要求,则可以使用以下代码段。

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.

file.length() 会给你文件的长度。

回答by spaghetti_code

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.

我认为,这是一个 goog 解决方案,如果您将 InputStream 转换为字节数组,那么您可以使用 createBlob 方法,该方法接受一个字节数组而不是 InputStream 和长度作为参数。对于转换,您可以使用 Apache Commons IO 中的 IOUtils。

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