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