2017-11-15 8 views
0

PostgresのBlobに格納されているバイナリデータがあります。私はJPAを介してdbと作業しますが、この場合重要ではありません。私は春のMVC @Controllerを持っていますが、エンドポイントからこのデータを提供できるはずです。そして私はのストリームのデータをメモリにすべてロードする理由があります。おおよそのように:Spring MVCコントローラからのBLOBストリーミングエラー

java.io.IOException: org.postgresql.util.PSQLException: ERROR: invalid large-object descriptor: 1

そして、なぜ私が知っている::

@Entity 
class MyEntity { 
    @Lob 
    Blob data; 
} 

@RequestMapping(...) 
public InputStreamResource getResource(...) { 
    return new InputStreamResource(myEntityRepository.findById(id).getData().getBinaryStream()); 
} 

これは、残念ながら、私を与えるあなたはブロブで作業するときは、run in transactionする必要があります。今、私は何を試してみました:

  1. を全体のコントローラメソッド@Transactionalの注釈 - 春は、サーブレット応答にストリームをコピーし始めたとき、それは、取引態様の外に既にあるので助けにはなりません。 : '(

  2. 私はまた、コントローラ内部I 場合は、それはすべての作品byte[]に入力ストリームをコピーする。しかし、これはまったくストリーミングされていないことを

byte[] data = IOUtils.toByteArray(myEntityRepository.findById(id).getData().getBinaryStream()); return new ByteArrayResource(data);

それは明らかに検証。アスペクトを行うアスペクトがであるという問題は、戻り値を取得してサーブレットレスポンスに変換するコントローラメソッドにを返します。

方法はありますか再注文の側面?他の解決策?

ありがとうございます!

編集: 残念ながらそうではありませんどの@EnableTransactionManagement(order = Ordered.HIGHEST_PRECEDENCE)を行うことによって、単純に動作するはずですようです。たぶん@EnableAspectJAutoProxy(proxyTargetClass = true)のためでしょうか?

Edit2: これは明らかにさらに一般的な問題です。 @RequestMapping注釈付きメソッドは、Streamを返しますが、呼び出しが完了した後でのみ(すべてのアスペクトを含み、@Transactional)、戻り値(Stream)はさらに処理されます。だから実際にはのクラスに、コントローラのメソッド、おそらくはServlet.doXXXのメソッドを呼び出すことになります。良いニュースはありません。

+0

春バージョン? –

+0

SPring Boot 1.5 –

+0

spring boot 2.0にある 'Spring Webflux'で移行することは可能ですか? –

答えて

0

私は、単純ではありませんが少しエレガントな解決策を見落としました。コントローラーのメソッドにHttpServletResponseまたはOutputStreamを注入して、コントローラーのメソッド内でStreamをコピーすることができます。 InputStreamResourceを返すだけでなく、うまくいきます。

関連する問題