Hibernate 4.2.2从未知长度的输入流创建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。

这是我现在正在使用的

 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),我将从Hibernate获取一个DataException(来自驱动程序:“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()); 

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

如下所示更改Dao中的save方法

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

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

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