问题
Hi i want to create a blob in hibernate from an inputstream, but i don't know the length of the stream.
Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(stream, length)
how can i crate a blob without knowing the length of the stream?
EDIT1
in older hibernate versions it was possible
http://viralpatel.net/blogs/tutorial-save-get-blob-object-spring-3-mvc-hibernate/
Blob blob = Hibernate.createBlob(file.getInputStream());
EDIT2
ok but it had an buggy implementation
return new SerializableBlob( new BlobImpl( stream, stream.available() ) );
stream.available isn't the real size
EDIT 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.
回答1:
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();
回答2:
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.
回答3:
Workaround could be to save input stream to a file then to read the file into blob.
回答4:
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.
回答5:
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);
}
回答6:
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));
来源:https://stackoverflow.com/questions/19908279/hibernate-4-2-2-create-blob-from-unknown-length-input-stream