Performance tuning of a Hibernate+Spring+MySQL project operation that stores images uploaded by user
- by Umar
Hi
I am working on a web project that is Spring+Hibernate+MySQL based. I am stuck at a point where I have to store images uploaded by a user into the database. Although I have written some code that works well for now, but I believe that things will mess up when the project would go live.
Here's my domain class that carries the image bytes:
@Entity
public class Picture implements java.io.Serializable{
long id;
byte[] data;
... // getters and setters
}
And here's my controller that saves the file on submit:
public class PictureUploadFormController extends AbstractBaseFormController{
...
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception{
MutlipartFile file;
// getting MultipartFile from the command object
...
// beginning hibernate transaction
...
Picture p=new Picture();
p.setData(file.getBytes());
pictureDAO.makePersistent(p); // this method simply calls getSession().saveOrUpdate(p)
// committing hiernate transaction
...
}
...
}
Obviously a bad piece of code. Is there anyway I could use InputStream or Blob to save the data, instead of first loading all the bytes from the user into the memory and then pushing them into the database?
I did some research on hibernate's support for Blob, and found this in Hibernate In Action book:
java.sql.Blob and java.sql.Clob are
the most efficient way to handle large
objects in Java. Unfortunately, an
instance of Blob or Clob is only
useable until the JDBC transaction
completes. So if your persistent class
defines a property of java.sql.Clob or
java.sql.Blob (not a good idea
anyway), you’ll be restricted in how
instances of the class may be used. In
particular, you won’t be able to use
instances of that class as detached
objects. Furthermore, many JDBC
drivers don’t feature working support
for java.sql.Blob and java.sql.Clob.
Therefore, it makes more sense to map
large objects using the binary or text
mapping type, assuming retrieval of
the entire large object into memory
isn’t a performance killer.
Note you
can find up-to-date design patterns
and tips for large object usage on the
Hibernate website, with tricks for
particular platforms.
Now apparently the Blob cannot be used, as it is not a good idea anyway, what else could be used to improve the performance? I couldn't find any up-to-date design pattern or any useful information on Hibernate website. So any help/recommendations from stackoverflowers will be much appreciated.
Thanks