There is an ongoing debate, generally related to media files, about whether to store media in the database or whether to store media on the fileystem and just store the reference in the database.
This article attempts to track some of the notable writings about the debate.
Keep in mind that the purpose of a database is to store data to be search and retrieved.<BR>It
It would be a rare case when you'd actually send a query to a database that consisted of an image blob (i.e. search for an image that matches certain binary data). More than likely, you'd perform a search for an image based on its meta-data like date, time, image name, or file system path. A good solution is to store the path to the medium and then simply build the reference URL for the client's browser to reference or have the application retrieve the medium from the file system and serve it up through the WebObjects adaptor. In the former case you can keep the media under the Web server (say image thumbnails) and, in the latter case, you can keep full size images anywhere else on the server's file system and server them up based on a user's profile (i.e. did they successfully check out?, etc).
Storing images in the database is generally a bad idea in my opinion. There's much more overhead in retrieving image data from a database then there is in just letting Apache serve up the image. Apache has been highly optimized just for this purpose. Databases generally have not.
My suggestion is to just store a URL for the image in the database and write that URL to the dynamic page. Or if you know the path is always going to be the same you could simply store the filename.
It seems that different people have different opinions on this topic. I've followed several threads on this and I still haven't come to a conclusion on the best design pattern.
With this design pattern fetching Product data doesn't directly load the images. Instead EOF will create faults representing the images.
The image data isn't fetched until the fault is fired by accessing the ProductPhoto fault object. So If you fetch 500 Products and batch them into groups of 10 with the [ WODisplayGroup|WO:Programming__WebObjects-Web Applications-Development-WODisplayGroup] then your first page would fetch only the first 10 images not the 500 (and only if there is a WOElement? or method that accesses the image data).
You can find an implementation of this design pattern for both toOne and toMany photos in the JavaRealEstate framework example in
I haven't had any problems storing images in our database (OpenBase). We have developed many "community" based sites with photo albums as well as an online dating service, both use the same methods that Robert talked about in his message.
I'd be interested to hear from others and there experiences with storing images in databases. You hear a lot of people saying "Don't do it, it won't perform well."...but have these people actually tried it? Or have they just been told not to do it. I have been very interested in this topic for a while now and I have done extensive searching but
never come up with any "correct" answer. I think it also depends on which database you use and how exactly the database itself stores images. I know that some are much better than others and personally this is where you'd most likely run into the performance hit (if any).
On the Fortnum & Mason online store http://www.fortnumandmason.comImage Removed, the product catalog is pretty image-heavy. Also, they (F&M) change the catalog and the associated images at least twice a year. So I wrote a tool that allows their product images to be uploaded into the database, simply for the purpose of having everything in a single place for
backup reasons. When a new catalog is ready to be deployed, the images are extracted from the database and placed under the webserver (since, as everyone notes, webservers are particularly good at vending images). The main F&M web application then gets all it's images from the webserver, as opposed to cached in the webobjects application after a fetch from the database.
Chuck Hill wrote something on the pros and cons of using the webserver yesterday - http://lists.apple.com/mhonarc/webobjects-dev/msg05564.htmlImage Removed (use 'archives', 'archives' as the username/password).
My opinion and experience FWIW, having done it both ways. I keep having this discussion so I'd thought I'd put it all down in one place.
- It's a little harder to manage. And you might still need a database to keep track of the images.
- It's harder to build a content management system that can upload images. WebDAV might address this issue.
Well, my 2 farthings.
One largish problem with storing them in the database is that EOF will cache the data, at least for a while. For a heavily loaded site or large contents this can really chew up the memory fast.
PetiteAbeille wrote about an EOF file system adaptor that may be of interest in relation to this question:
We grab images from the database in our WebObjects application (electronic logbook). It is a very heavily accessed site and allows users to make entries that have text, images and other attachments. We have found additional "pros" for loading images from a database.
Whether you choose database storage or filesystem storage really depends on your application. For our application, the electronic logbook is becoming more integrated with other systems and the database has turned out to be critical in that integration.
I happily store images in the database, but... my clients use Oracle or FrontBase. The very now though I have the misfortune to work on an application which has to use the MS-SQL thing: seems it really does not support BLOBs well (actually, the database admin just plain told me "do not use a BLOB in your tables, ever--we have the worst experience with them").
The reason I am writing: before deciding where to store your images, do check the concrete database to be used. If FrontBase or Oracle, you probably would want to store them in the database, if MS-SQL, you probably would want to store them in the filesystem
I'm a little WORusty at the moment, so please excuse any gaffes in this. WO 5.3 has renewed my interest in WebObjects.
Generally, I create a direct action method for dispensing the images. Something like this in your DirectAction (except that you might want to add validation if you don't want just anyone getting to your images by hacking the URL):
public WOActionResults imageAction()
// PictureTest is an EOEntity with a BLOB containing the image data
PictureTest pt = getPictureTestEO();
private PictureTest getPictureTestEO()
// Yes - you can get the session in a direct action
// you just need to be prepared to deal with one not existing
// whether you return an image if no session exists depends on
// on your own application needs.
WOSession theSession = existingSession();
EOEditingContext ec = (theSession == null) ? new EOEditingContext() : theSession.defaultEditingContext();
String picid = (String)request().formValueForKey("picid");
return (PictureTest)EOUtilities.objectMatchingKeyAndValue(ec, "PictureTest","id", new Integer(picid));
private WOResponse jpegResponseWithData(NSData theData)
// This method returns the data so that the browser
// recognizes the image type. In this particular application
// I've just hardcoded a mime type of JPEG because I only
// use JPEG images, but a better way would be to store the mime-type
// that corresponds to the image data in the BLOB as a separate
// field. I might revise this sample later on to show that.
WOResponse response = WOApplication.application().createResponseInContext(context());
Then, in your WOComponent, you create a virtual accessor like this:
public String imageURL()
return context().directActionURLForActionNamed("icon", null) + "?picid=" + pictureItem.id();
in this case, pictureItem is a PictureItem EOEntity instance that I use in a WORepetition - I'm just pulling the id number from the currently selected picture.
This approach eliminated a lot of the overhead that you get by just binding directly to the EOEntity's attribute, and really isn't much extra work.
Storing images in the database is generally a bad idea for a whole slew of reasons. First and foremost, it is loads slower than serving images directly from the web server and it completely bypasses numerous automatic "optmiziations" that are present when serving from a filesystem. If it can't be avoided, it can't be avoided.... however, if you have any hopes of scaling your solution to a large community of users or a heavy hit rate, expect to expend a lot of engineering and hardware dollars making images-in-the-database go fast.
One thought; if an image needs to be refreshed and you are worried about client-side or proxying-firewall caching, rename the image in the filesystem (or move it) and generate a new URL-- this should be the image managers responsibility.Category:WebObjects