Guybrush Threepwood Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 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? Zitieren
kingofbrain Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 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 Zitieren
flashpixx Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 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 Zitieren
dr.dimitri Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 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 Zitieren
kingofbrain Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 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 Zitieren
Guybrush Threepwood Geschrieben 16. Oktober 2009 Autor Geschrieben 16. Oktober 2009 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. Zitieren
kingofbrain Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 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 Zitieren
flashpixx Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 Da können Dir vielleicht dann die zwei anderen Kollegen weiterhelfen. Bei Hibernate muss ich leider aktuell passen, produktiv habe ich noch nicht mit gearbeitet. JDBC etc ist aber kein Problem Zitieren
kingofbrain Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 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 Zitieren
dr.dimitri Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 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 Zitieren
kingofbrain Geschrieben 19. Oktober 2009 Geschrieben 19. Oktober 2009 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 Zitieren
Empfohlene Beiträge
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.