Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Es sollen Dateien in einer Datenbank gespeichert werden. Das klappt auch bei kleinen Dateien, sobald die Dateien aber etwas größer werden kommt beim Aufruf von

entityManager.merge(entity);

eine OutOfMemoryException: Java Heap Space.

Die Datei ist im zu speichernden Objekt folgendermaßen enthalten:


@Lob
@Column(name = "rawData")
private byte[] rawData;
[/PHP]

Hat jemand eine Idee wie man das Problem lösen kann?

Geschrieben

Ja, gib dem Java-Prozess mehr Speicher (-Xmx als Parameter an die VM).

ich vermute, der EntityManager muss die gesamte Datei im Speicher halten, um sie per JDBC an die Datenbank zu schicken. Deshalb wird eine Lösung, die nach und nach Daten aus einem Stream liest und die bereits gelesenen Daten verwirft, nachdem sie zum Server geschickt wurden, nicht funktionieren. Ein Statement muss meines Wissens nach immer komplett an das RDBMS geschickt werden.

Schöne Grüße,

Peter

Geschrieben
Ein Statement muss meines Wissens nach immer komplett an das RDBMS geschickt werden.

Ein Statement ja. Man kann das Problem aber auch per Stream lösen z.B. via BLOB oder CLOB Feldern, das muss dann aber durch den JDBC Treiber unterstützt werden

Geschrieben
Ein Statement muss meines Wissens nach immer komplett an das RDBMS geschickt werden.

Blob Daten werden im allgemeinen per OutputStream in die Datenbank geschrieben. Daher ist es sehr wohl möglich eine Datei häppchenweise in die Datenbank zu schreiben. Jede DB ist da aber im Detail ein bissl anders. Eines haben sie aber gemeinsam: Es gibt eine Doku in der das Vorgehen mit Blobs und JDBC beschrieben wird.

Dim

Geschrieben

Ah ja, gut zu wissen. Dass man bei JDBC inhaltlich große Felder per Stream schicken kann, war mir nicht bewusst.

Wie das ein EntityManager (welche Implementierung wird denn verwendet?) löst, ist wohl dann Sache der konkreten Implementierung.

Peter

Geschrieben
welche Implementierung wird denn verwendet?) r

Gute Frage, nächste Frage

Also das ist der javax.persistence.EntityManager aber da spielt auch Hibernate irgendwie mit rein.

Ist aber ein größeres Projekt und ich hab keine Ahnung was da jetzt genau und wie verwendet wird da ich auch erst seid kurzem Java mache...

Das Ganze läuft übrigens innerhalb eins Tomcat Webservers aber sollte ja egal sein.

Geschrieben
Also das ist der javax.persistence.EntityManager aber da spielt auch Hibernate irgendwie mit rein.

Dann haben wir ja die Implementierung: Hibernate. javax.persistence.EntityManager ist nur die Schnittstelle, die dann von Hibernate implementiert wird.

Ob Hibernate allerdings eine Möglichkeit gibt, die von den beiden anderen angesprochene Speicherung per Stream durchzuführen, kann ich Dir nicht sagen. Auf die Schnelle hat mir auch eine Suche nichts gegeben.

Sollte es mit Hibernate als EM nicht funktionieren, dann kannst Du natürlich - einen entsprechenden JDBC-Treiber vorausgesetzt - den direkten Weg über JDBC gehen. Da können Dir vielleicht dann die zwei anderen Kollegen weiterhelfen.

Peter

Geschrieben

Ich habe jetzt mal die JPA Spezifikation durchsucht. Scheinbar wird dort nicht geregelt, wie eine Implementierung ein großes Binärobjekt speichert, nur dass es gekonnt werden muss.

Gleichzeitig habe ich mal die Dokumentation zu Hibernate durchsucht und gesehen, dass es in der Klasse org.hibernate.Hibernate eine statische Methode createBlob(InputStream) gibt. Das könnte bedeuten, dass funktioniert, was Du willst (allerdings abseits vom Standard JPA), es muss aber nicht sein.

Ich denke, der beste Weg ist hier, sich gleich auf JDBC zu verlassen und für diesen Zweck ein althergebrachtes JDBC-DAO zu schreiben. Das sollte - entsprechend gekapselt - gut funktionieren und ansonsten die Verwendung von JPA nicht beeinträchtigen.

Peter

Geschrieben
eine statische Methode createBlob(InputStream)

Ein InputStream bietet aber keine Möglichkeit etwas zu schreiben. Es wird ein ein OutputStream benötigt um einen LOB zu befüllen. Eine InputStream wird verwendet um ihn zu lesen.

Dim

Geschrieben

Es wird hier ja auch gelesen: in den BLOB hinein. Am Ende erhalte ich einen aus dem InputStream gefüllten BLOB von der Methode zurück.

Das sollte schon das sein, was gewünscht ist. Der BLOB muss dann natürlich trotzdem noch in die Datenbank kommen, aber das ist ja das Problem von Hibernate. Mit dem erzeugten BLOB befüttere ich meine Beans, den Rest erledigt das ORM.

Peter

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...