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

时间:2013-11-11 14:04:08

标签: java hibernate stream blob

您好我想从输入流创建一个blob in hibernate,但我不知道流的长度。

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

如何在不知道流的长度的情况下创建一个blob?

EDIT1

在较旧的hibernate版本中可能

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

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

EDIT2

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

返回新的SerializableBlob(new BlobImpl(stream,stream.available()));

stream.available不是真正的大小

编辑3

我试过

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

但是conn只是来自c3p0的NewProxyConnection。

6 个答案:

答案 0 :(得分:3)

以下是我现在使用的

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

答案 1 :(得分:0)

尝试传入InputStream,长度为-1:

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

这适用于SQL Server 2008.似乎Hibernate将此值直接传递给JDBC驱动程序,因此根据您的数据库驱动程序,这可能会也可能不会。

注意:如果我传入不正确的流长度(包括0),我将从Hibernate获取一个DataException(来自驱动程序:“com.microsoft.sqlserver.jdbc.SQLServerException:流值不是指定的长度。指定长度为10,实际长度为13.“)。长度为-1时,它总能正常运行而不会抱怨,数据会成功保存到数据库中。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我理解我的回答与您的问题略有不同。但这可能会帮助其他人降落在这里。根据我的要求,我将绝对文件路径作为创建blob的输入。如果您也有类似的要求,可以使用以下代码段。

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

file.length()将为您提供文件的长度。

答案 4 :(得分:-1)

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

答案 5 :(得分:-1)

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

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