Update: Steffen Glomb dropped me a note to point out that I'd made a mistake in my code excerpt (I had written session.update(be); where I should have had session.refresh(be); so I have amended the sample accordingly. Thanks Steffen!
Another Hibernate gotcha. The easiest way to create a java.sql.Blob in Hibernate from an input stream is to call the static method Hibernate.createBlob(InputStream). The problem with this is that it's still "attached" to the originating input stream even once the blob has been inserted into the database. When you retrieve the input stream with the getBinaryStream method, you will typically then see the following error:
java.sql.SQLException: could not reset reader at org.hibernate.lob.BlobImpl.getBinaryStream(BlobImpl.java:83) at org.hibernate.lob.SerializableBlob.getBinaryStream(SerializableBlob.java:39) ... etc.
The way to avoid this is to replace the Blob with the "real" database backed implementation representing the data that's been stored. To do this all you have to do is refresh the entity that the blob is a property on:
public BlobEntity createBlobEntity(final InputStream input) { final Blob blob = Hibernate.createBlob(input); final BlobEntity be = new BlobEntity(); be.setBlob(blob); session.save(be); session.flush(); session.refresh(be); return be; }
This should avoid the problem entirely.