Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Streaming Data through Spring JDBC, unknown length

Tags:

java

spring

jdbc

I currently have an application that inserts byte[] into our DB through the use of Spring JDBC [SqlLobValue]. The problem is, this is not a scalable way to take in data, as the server is buffering all the data in memory before writing to the database. I would like to stream the data from the HttpServletRequest Inputstream, but all the constructors I can find for any classes that take an Inputstream as an argument also require the content length as an argument. I do not, and will not, require the user to know the content length when POSTing data to my application. Is there a way around this limitation?

I can find no documentation about what happens if I pass -1 for content length, but my guess is it will throw an Exception. I'm not sure why they couldn't just have the stream keep reading until the read(...) returns -1, the required behavior of an InputStream.

like image 965
Gandalf Avatar asked Apr 22 '09 16:04

Gandalf


1 Answers

I presume you meant "InputStream" rather than "OutputStream". I tried this out, but I was having bigger problems with my JDBC driver, so I am unsure if this actually works.

InputStream inputStream = httpServletRequest.getInputStream();

int contentLength = -1; // fake, will be ignored anyway
SqlLobValue sqlLobValue = new SqlLobValue(
    inputStream,
    contentLength,
    new DefaultLobHandler() {
        public LobCreator getLobCreator() {
            return new DefaultLobHandler.DefaultLobCreator() {
                public void setBlobAsBinaryStream(PreparedStatement ps, int paramIndex, InputStream binaryStream, int contentLength) throws SQLException {
                    // The contentLength parameter should be the -1 we provided earlier.
                    // You now have direct access to the PreparedStatement.
                    // Simply avoid calling setBinaryStream(int, InputStream, int)
                    // in favor of setBinaryStream(int, InputStream).
                    ps.setBinaryStream(paramIndex, binaryStream);
                }
            };
        }
    }
);

jdbcTemplate.update(
    "INSERT INTO foo (bar) VALUES (?)",
    new Object[]{ sqlLobValue }
);
like image 77
Adam Paynter Avatar answered Nov 03 '22 21:11

Adam Paynter