i'm using resteasy and saving blobs with hibernate
i've configured the open session in view
my rest-handler is non-transactional, my service which retrieves the java.sql.blobs is transactional.
The problem: after retrieving the blob in the service the jdbc-connection is closed by the HibernateTransactionManager:doCleanupAfterCompletion (the hibernate session is not closed)
so rest can't read the blob stream later, because it works only if the same jdbc-connection is still open
how can i hibernate teach not to close the jdbc-connection after the transactional service-function?
It should close it when the session is closed
i solved it by creating a Provider for Blob, adopded from InputSTream-Provider
@Provider
@Produces("*/*")
public class BlobProvider implements MessageBodyWriter<Blob> {
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return Blob.class.isAssignableFrom(type);
}
public long getSize(Blob blob, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return -1;
}
public void writeTo(Blob blob, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
SessionFactory sessionFactory = (SessionFactory) Utils.getBean("sessionFactory");
sessionFactory.getCurrentSession().beginTransaction();
InputStream inputStream = null;
try {
inputStream = blob.getBinaryStream();
int c = inputStream.read();
if (c == -1) {
httpHeaders.putSingle(HttpHeaderNames.CONTENT_LENGTH, Integer.toString(0));
entityStream.write(new byte[0]); // fix RESTEASY-204
return;
} else
entityStream.write(c);
ProviderHelper.writeTo(inputStream, entityStream);
} catch (SQLException e) {
Utils.logError(e);
} finally {
if (inputStream != null)
inputStream.close();
}
sessionFactory.getCurrentSession().getTransaction().commit();
}
}