Hibernate: Wie am besten in byte[] streamen?

  • Themenstarter Themenstarter tuxedo
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
T

tuxedo

Gast
Servus ...

ich hab die Anforderung Dateien in einer mit Slony geclusterten PostgresSQL-DB zu speichern. Als Persistenzschicht kommt Hibernate zum einsatz.

Da Slony nur "bytea" und nicht "oid" BLOBs replizieren kann, muss ich auf den Feldtyp "bytea" setzen.

Soweit ich rausgefunden habe, wird das mit Hibernate auf "byte[]" gemapped.

Die Deklaration dazu war einfach:

Java:
    @Column(name = "entry")
    private byte[] mEntry;


Damit wird in der DB die Spalte mit Typ "bytea" angelegt. Soweit so gut.

Speichern kann ich darin mehr oder weniger auch schon.

Problem ist jetzt nur: Was mach ich mit Dateien die größer als der Java zur Verfüpgung stehende Speicher sind? Die kann ich unmöglich komplett in den Speicher als byte[] laden.

Ich muss das ganze also irgendwie streamen, sprich Hibernate den Inputstream der Datei mitgeben, so dass beim "persist()" aufruf am EntityManager der Stream gelesen und dessen Inhalt direkt in die DB geschoben wird.

Nur hab ich keinen Schimmer wie das geht. Google hat mich immer nur zu Beispielen mit "oid" BLOBs gebracht. Da scheint das aber komplett anders zu funktionieren.

Bei reinem JDBC wäre es recht einfach zu lösen. Da komm ich nehazu Problemlos an den Stream ran. Aber da Hibernate alles in sich kapselt steh ich hier vor nem Problem.

Hat jemand nen Tipp für mich?

Gruß
Alex
 
So, auch nach einem Tag recherchieren bin ich noch nicht weiter. Hat keiner ne Idee oder nen Tipp?

- Alex
 
Ja, soweit war ich schon. Problem ist nur, dass die einzelnen Felder serialisierbar sein müssen. Hab trotz CustomType noch keinen Weg gefunden wie ich eine Entity-Klasse mit einem Stream kombiniere. Auch wenn ich in der Entity-Klasse einen extra Container benutze der den Stream enthält geht's nicht.

Habs übergangsweise jetzt so gelöst dass ich bis 10MiB unterstütze und diese komplett in ein byte[] einlesen und das dann persistiere.

Hast du vllt. ein funktionsfähiges Beispiel?

- Alex
 
Blobs kann ich nicht nehmen, da die zugrundeliegende Datenbank (Postgres) mit Slony repliziert wird, und eben diese Replikation mit BLOBs nicht umgehen kann, da dort kein Trigger registriert werden kann, welcher aber für eine Replikation notwendig ist. Ergo bleibt nur "bytea".

Aber das steht ja schon im ersten Post den du sicher gelesen hast 😉

- Alex
 
Hab ich wohl überlesen, sorry.

Ich würde übrigens Binärdaten nicht in der DB ablegen, sondern das Dateisystem dafür verwenden (in der DB also nur den Pfad zur Datei ablegen). So machens auch die meisten großen Webapps (z.B. Flickr).
 
Ja, so würd' ichs auch machen. Aber ich hab nunmal die Anforderung dass das Zeug in die DB muss die eben für "High Availability" repliziert wird. Kann also erstmal nix dran ändern. Zumindest nicht in der noch zur Verfügung stehenden Zeit. Aber auch das steht in meinem ersten Post 😉
 
Halte doch den InputStream im Projo in einer transient-Variable. Eine weitere Variable welche in ein Blob gemappt wird.
Beim persistieren hatt das Projo einen Stream auf die Daten. Dein CustomType streamt dann in das andere gemappte Feld.

Code:
class Pojo{
   private transient InputStream byteStream;
   private byte[] data;
}

Der byteStream wird befüllt, das data-Attribut wird mit einem CustomType gemappt.
Der CustomType nimmt anstatt des data-Inhalts den InputStream und streamt direkt in die DB
 
Genau das hatte ich probiert. Aber da kams nochmal zu einem anderen Problem. Habs nur dummerweise nicht dokumentiert. Weiß nur noch dass ich mich mit dem Problem im Kreis gedreht hab. Werde es wohl oder übel nochmal nachstellen müssen.

- Alex
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben