I have the following task:
- pass a file through SOAP
- save the file in a PostgreSQL database
The file should be passed as a stream.
For the first part of the task I used MTOM mechanism. It works fine. For the second part I tried to use setBinaryStream method. To check that the method is truly streaming I restricted Java heap to 128 Mb and passed a ~900Mb file. As a result I got out of memory exception.
So I tried to use Large Objects. This mechanims normally works with no exception. But I do not want to use this mechanism because of extra operaitons needed while object deletion and because of some security considerations.
Here the used code with setBinaryStream:
conn = getConnection();
PreparedStatement ps = null;
DataHandler dh = streamType.getHandler();
InputStream is = null;
try {
is = dh.getInputStream();
ps = conn.prepareStatement("INSERT INTO files VALUES (?, ?)");
ps.setString(1, streamType.getName());
ps.setBinaryStream(2, is);
ps.executeUpdate();
}
...
And this one with Large Objects:
conn = getConnection();
DataHandler dh = streamType.getHandler();
PreparedStatement ps = null;
InputStream is = null;
try {
is = dh.getInputStream();
conn.setAutoCommit(false);
LargeObjectManager lobj = ((org.postgresql.PGConnection) conn).getLargeObjectAPI();
int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
byte buf[] = new byte[65536];
int s, tl = 0;
while ((s = is.read(buf, 0, 65536)) > 0) {
obj.write(buf, 0, s);
tl += s;
}
obj.close();
ps = conn.prepareStatement("INSERT INTO fileslo VALUES (?, ?)");
ps.setString(1, streamType.getName());
ps.setInt(2, oid);
ps.executeUpdate();
conn.commit();
}
...
May be there is some other way to stream data into the database without Large Objects?