11

こんにちは、入力ストリームから休止状態でブロブを作成したいのですが、ストリームの長さがわかりません。

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

ストリームの長さを知らずにブロブをクレートするにはどうすればよいですか?

編集1

古い休止状態のバージョンでは可能でした

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

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

EDIT2

わかりましたが、バグのある実装がありました

return new 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 です。

4

6 に答える 6

4

ここに私が今使っているものがあります

Session currentSession = getSessionFactory().getCurrentSession();
Blob blob = Hibernate.getLobCreator(currentSession).createBlob(new byte[0]);
OutputStream setBinaryStream = blob.setBinaryStream(1);
Utils.fastChannelCopy(input, setBinaryStream);
setBinaryStream.close();
于 2015-12-18T15:12:55.903 に答える
0

InputStream と -1 の長さを渡してみてください。

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

これは SQL Server 2008 で動作します。Hibernate はこの値を直接 JDBC ドライバーに渡すように見えるため、データベース ドライバーによっては動作する場合と動作しない場合があります。

注: 間違ったストリーム長 (0 を含む) を渡すと、Hibernate から DataException が発生します (ドライバーから: "com.microsoft.sqlserver.jdbc.SQLServerException: The stream value is not the specified length. The specified length. The specified length.は 10 でしたが、実際の長さは 13 です。")。長さが -1 の場合、常に問題なく動作し、データはデータベースに正常に保存されます。

于 2013-11-26T17:10:05.757 に答える
0

回避策として、入力ストリームをファイルに保存してから、そのファイルを BLOB に読み込むことができます。

于 2014-09-26T09:21:48.150 に答える
0

私の答えがあなたの質問と少し違うことは理解しています。しかし、これはここに着陸する他の人を助けるかもしれません. 私の要件では、ブロブを作成するための入力として絶対ファイルパスを取得しています。同様の要件がある場合は、以下のスニペットを使用できます。

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

file.length() は、ファイルの長さを示します。

于 2016-04-15T10:50:39.010 に答える
-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);
}
于 2013-12-20T11:59:18.667 に答える
-2

InputStream をバイト配列に変換すると、それは goog ソリューションだと思います。そのため、InputStream の代わりにバイト配列と長さをパラメーターとして受け入れる createBlob メソッドを使用できます。変換には、Apache Commons IO の IOUtils を使用できます。

Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(IOUtils.toByteArray(stream)); 
于 2017-04-03T12:20:58.863 に答える