2012-03-27 10 views
7

Ich möchte große Anlagen (500 MB, vielleicht, wenn möglich, auch> 2 GB) in einer Datenbank speichern. Ich weiß, dass die Vor- und Nachteile dieser Vorgehensweise sehr häufig diskutiert werden, aber das steht nicht im Mittelpunkt meiner Frage.Speichern Blob mit einem Stream von EJB zu Datenbank (auf eine effiziente Weise Speicher)

Der herkömmliche Weg Blobfelder in EJB3 mit JPA des Speicherns ist einen Code wie folgt zu verwenden:

@Lob 
private byte[] data; 

dies ein Problem wird, wenn große Datenquellen der Handhabung, weil der gesamte Byte-Array im Speicher gespeichert wird.

Ich habe versucht, es zu Blob zu ändern:

@Lob 
private Blob data; 

Aber dies führt zu dem gleichen Problem. Beim Aufruf

// session: Hibernate session. 
// Actually, I'd like to stay with JPA's abstraction and not 
// reference Hibernate directly, if possible 
Blob data = session.createBlob(inputStream, lengthOfStream); 

die CreateBlob-Methode erstellt ein ByteArray aus dem InputStream.

Aufgrund der ORM-Zuordnung frage ich mich auch, wie man mit dem Einfügen der Daten umgehen soll. Eine Idee war es, eine Entitätsvariable

@Lob 
private byte[] data; 

Dass ich nie zu machen. Auf diese Weise wird das Datenbankschema erstellt. Da die @Lob-Annotation jedoch faul ist, wird mein Speicher nicht aufgebläht.

Und dann schreiben

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); 

Eine Lösung, die ich über stolperte sieht nett aus, aber JPA nicht verwenden: Grooviest way to store a BLOB in a database?

Hat jemand einen Rat, wie dies zu tun?

+0

Gibt es einen Grund, einen Blob anstelle eines Dateipfads zu verwenden? – siebz0r

+0

Ja, Portabilität. Die Idee besteht darin, die Daten in der Datenbank zu speichern und sie im Dateisystem zwischenzuspeichern. Auf diese Weise müssen nur die Datenbank und das Jar auf ein neues System kopiert werden - die Dateien werden automatisch von der Datenbank in das Dateisystem zwischengespeichert. –

+0

Ich denke nicht, dass dies eine effiziente Art der Speicherung ist. Wenn der Pfad des Speichers konfigurierbar ist, muss der Pfad in der Datenbank nur ein Postfix des ursprünglichen Pfads sein. Der Nachteil ist, dass Sie die db, jar und Dateien verschieben müssen. Aber ich denke, die Vorteile überwiegen hier. – siebz0r

Antwort

1

@Lob-Annotation kann auf ein serialisierbares Objekt angewendet werden. Sie könnten dann erklären:

@Lob 
private MySmartLOB data; 

und

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 
    } 
} 

Das könnte funktionieren, die Hoffnung, dass die zugrunde liegende JPA-Implementierung intelligent genug ist, eine Object direkt geleitet, um den JDBC-Strom zu liefern und nicht irgendeine Art von hässliches ByteArrayOutputStream.