2012-03-27 7 views
7

大きな添付ファイル(可能であれば500Mb、おそらくは2Gb以上)をデータベースに保存したい。そうすることの長所と短所が非常に頻繁に議論されることは分かっていますが、それは私の質問の焦点では​​ありません。EJBからデータベースへのストリームを使用してBLOBを保存する(メモリ効率的な方法で)

JPAとEJB3のBLOBフィールドを記憶する従来の方法は、以下のようなコードを使用することである:全体のバイト配列は、メモリに保存されているため、膨大なデータソースを処理するとき

@Lob 
private byte[] data; 

これは問題となります。

私は、BLOBにそれを変更しようとしました:

@Lob 
private Blob data; 

しかし、これは同じ問題がありました。呼び出すときには、createBlobメソッドはinputStreamからbyteArrayを作成します。

ORMマッピングのため、私はデータの挿入をどのように処理するのかと思います。 ひとつのアイデアは、エンティティ変数私が使用することはありません

@Lob 
private byte[] data; 

を作ることでした。このようにして、データベーススキーマは構築されます。しかし、@Lobアノテーションは怠惰なので、私の記憶を膨らませません。その後、

そして、私がつまずいた一つの解決策は全体の良さそうに見えますが、JPAを使用しない

entityManager.persist(dataObject); 
// The following lines are _completely_ imaginatory!! 
query.prepare("update DataObject d set d.data = :dataInputStream where d = :dataObject"); 
query.setProperty("dataObject", dataObject); 
query.setProperty("dataInputStream", someDataInputStream); 

を書く: Grooviest way to store a BLOB in a database?

を誰もがこれを行う方法のアドバイスがありますか?

+0

ファイルパスの代わりにBLOBを使用する理由はありますか? – siebz0r

+0

はい、移植性。その考え方は、データをデータベースに格納し、ファイルシステムにキャッシュすることです。この方法では、DBとjarファイルだけを新しいシステムにコピーする必要があります。ファイルはDBからファイルシステムに自動的にキャッシュされます。 –

+0

これは効率的な保管方法ではないと思います。ストレージのパスが設定可能な場合、データベースのパスは最初のパスの後置にする必要があります。欠点は、db、jar、およびファイルを移動する必要があることです。しかし、私は賛否両論がここの短所より重要だと思う。 – siebz0r

答えて

1

@Lobアノテーションは、Serializableオブジェクトに適用できます。基礎となるJPAの実装では、直接JDBCストリームにパイプにObjectOutputStreamを供給するのに十分にスマートであることを期待して

@Lob 
private MySmartLOB data; 

public class MySmartLOB implements Serializable { 
    private void writeObject(java.io.ObjectOutputStream out) 
      throws IOException { 
     // tranfer data from local storage to 'out' 
    } 
    private void readObject(java.io.ObjectInputStream in) 
      throws IOException, ClassNotFoundException { 
     // tranfer data from 'in' to local storage 
    } 
} 

これは仕事ができる、をしてではなく、いくつかの並べ替え: その後、宣言し醜いByteArrayOutputStream

関連する問題