Hibernate 4.2.2 создание blob из входного потока неизвестной длины
Привет я хочу создать blob в спящем режиме из inputstream, но я не знаю длину потока.
Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(stream, length)
Как я могу упаковывать шарик, не зная длины потока?
EDIT1
в старых версиях hibernate это было возможно
http://viralpatel.net/blogs/tutorial-save-get-blob-object-spring-3-mvc-hibernate/
блоб блоб = Зимовать.createBlob (файл.getInputStream());
EDIT2
хорошо, но у него была багги реализация
вернуть новый SerializableBlob (новый BlobImpl (stream, stream.available () ));
поток.доступен не реальный размер
редактировать 3
пробовал
session.doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
LargeObjectManager lobj = ((org.postgresql.PGConnection) conn).getLargeObjectAPI();
но conn-это просто NewProxyConnection от c3p0.
6 ответов
вот что я использую сейчас
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), я получу исключение DataException из Hibernate (от драйвера: "com.Microsoft.от SQLServer.интерфейс jdbc.SQLServerException: значение потока не является указанной длиной. Этот указанная длина составила 10,фактическая-13."). При длине -1 Он всегда работает без жалоб, и данные успешно сохраняются в базе данных.
Я понимаю, что мой ответ немного отличается от вашего вопроса. Но это может помочь другим, кто высадится здесь. Для моего требования я получаю абсолютный путь к файлу в качестве входных данных для создания blob. Если у вас тоже есть подобное требование, вы можете использовать приведенный ниже фрагмент.
Session session = sessionFactory.getCurrentSession();
File file = new File(filePath);
Blob blob = Hibernate.getLobCreator(session).createBlob(new FileInputStream(file), file.length());
.length () даст вам длину файла.измените метод save в 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);
}
Я думаю, это решение goog, если вы преобразуете InputStream в массив байтов, поэтому вы можете использовать метод createBlob, который принимает массив байтов вместо InputStream и length в качестве параметра. Для преобразования вы можете использовать IOUtils из Apache Commons IO.
Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(IOUtils.toByteArray(stream));