I’d like to start a discussion about the approach of persistence layers in general.  This is in no way a criticism of Hibernate and the sterling work done by the team.  For a persistence layer which maps to beans, there is nothing else which comes close.
I guess what I want to talk about stems into the approach of software development in general.  I have a particular philosophy for design of applications: that most code can be simple, generic and reusable.  It’s the basic precept of object-orientation, but how often do you see developers happy to use high level classes, but then "hard-code" just about everything else.  The argument is that things can not be totally genericized, because there are always exceptions to simple rules.  My approach is that most things can be automatic and still allow forks to be implemented where needed.  Most people I suggest this to think I’m crazy (perhaps I am, but I thought it was for different reasons).
Shameless plug:  My project Atomic Objects aims to create an object environment which creates a virtual object space in which dynamic interconnection of objects can occur.  It’s basically an inversion of control environment, on steroids.
http://atomic.catchpole.net/
I don’t actually like databases.  In so much as they don’t fit OO programming paradigms so well.  In a perfect world, persistence would occur to an object-oriented database within the application itself (funnily enough, Atomic has one of those).  This does not account for the fact that databases currently offer a swag of technical, business and integration value.  If we could wave a magic wand perhaps we would retro-fit something which provides all this yet more tightly integrated with Java (or any other OO language).  This isn’t going to happen though, so I am happy to see the value in using persistence layers and databases.  I just wonder if the gap in the technologies is going to get closer over the coming years, or further apart.
Anyway, one of the golden rules of the Hibernate team is “don’t write your own persistence layer”.  As Atomic has some particular requirements, I am currently thinking I may break this rule.
Database reflection is a wonderful thing.  Middlegen and HBM2Java help us create the map between database tables and beans.  In a normal programming environment it is almost essential to have beans that map the tables of the database.  You need to generate (automatically or otherwise) the class for this so that you have something to code against.  Atomic though, uses reflection (via proxies) to bind various objects and method calls together.  In this case, a simple database schema can be reflected at runtime using the Meta-data from JDBC.  These can be mapped to 1 to 1 beans, other objects never intended as mapping beans or just as simple “soft collections” of values.  (I think Spring Persistence may use a similar “map it to whatever” approach).
Most column types are automatic.  A String is a String.  An Integer is an Integer.  A foreign-key is a foreign-key.  A well-designed schema does not tell us everything we need to know to properly map everything into the Java world.  Especially strange relationships and non-constrained keys, or things about the schema we want to ignore or change.
My approach though, is to map extra information as deltas or overlays.  Allow runtime defaults to apply unless otherwise specified.  This means that if the schema changes, adding or removing columns which aren’t used, the automatic mapping just works around it.  No source code regenerate or mapping files to edit.
I admit that a fully dynamic environment is an all or nothing proposition.  It must provide enough features to be useful or it becomes more a hassle than it’s worth.  Just like WYSIWYG editors.  A nice idea, but useless if they trivialize the situation and don’t supply the fine control you need for real life applications.
Wouldn’t it be nice to open any old database, drop an existing bean (or collection or whatever) onto a table, having it try to match field to column names, allowing you to map anything that differs.  I know this trivialises the situation and in more cases there is more work to do than that.  I just worry that software will always be hard to write because of the assumption that everything is difficult and nothing can be reliably automated.