Lots of recent posts on O/R frameworks from Mike, Joe (here and here), Joe, Anthony, Charles, Brett and Gerhard, to name a few. (And just to be a sneak, I mentioned something about this a couple weeks ago.)
One note: I may come at this from a different angle than some people -- I'm the primary author of SPOPS, an object persistence framework in Perl that can use DBI datasources (like JDBC with less metadata but faster), GDBM keyed access and LDAP. I also work almost entirely on heterogeneous systems where data are accessed by multiple languages and multiple systems.
I've never quite understood why it's a good thing to be able to pull in an entire object graph when you retrieve an object. It smacks of peekaboo logic: something is happening behind the scenes, and it's magical when it works, but have fun debugging it if something goes awry. Sure, it's fun to program a system to traverse graphs and all that CS stuff, but how often do you really need all that data? And what's wrong with simply doing:
Customer cust = db.fetch( customerID ); List custOrders = cust.getOrders();
The code is simple, straightforward, and easy to understand. Some argue that it's useful to do something like:
for ( Iterator it = custOrders.iterator(); it.hasNext(); ) { Order order = (Order)it.next(); if ( order.meetsSomeCrazyCondition() ) { order.setSomeValue(); } } cust.save(); // saves all modified orders too!
But this is just more peekaboo logic: why not just save each order as you go? If you're worried about potential multiple database accesses, just hit up my hero Martin Fowler for some Unit of Work action so they're all submitted at once.
Querying is another issue that Mike brings up. I hate to sound like a curmudgeon, but what's wrong with SQL? Everyone knows it, it's simple to work with and, for most tasks, it's portable from database to database. It's ugly scattered around your system, but then any sort of query would be ugly scattered around your system. Centralizing, frequently in some sort of configuration file, is a good thing.
This brings us to the next point. I agree wholeheartedly with Mike on this: being able to change a configuration file and then generate your persistent classes is amazingly powerful -- talk about flexibility! (There's another entry just about this around the corner...)
I also have little patience for frameworks that don't let me retrofit them to an existing schema, or that require me to change my database schema to accommodate them. For instance, I can't believe how dumb the Entity Bean frameork is to not work out of the box with some sort of framework that supports existing sequences or identity fields for autogenerated primary keys. It's not like it's a hard problem!